mirror of
https://github.com/JHUAPL/Glum.git
synced 2026-01-07 00:03:50 -05:00
Changes for 2.0.0:
Bulk updates relating to the 2.0.0 public release of GLUM.
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-16"/>
|
||||
<classpathentry kind="lib" path="lib/guava-18.0.jar" sourcepath="lib/guava-18.0-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
@@ -16,7 +12,7 @@
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="lib" path="lib/miglayout-3.7.2-swing.jar">
|
||||
<classpathentry kind="lib" path="lib/miglayout-3.7.2-swing.jar" sourcepath="lib/miglayout-3.7.2-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
</attributes>
|
||||
|
||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
bin/
|
||||
doc/
|
||||
|
||||
unused/
|
||||
460
.settings/org.eclipse.jdt.core.prefs
Normal file
460
.settings/org.eclipse.jdt.core.prefs
Normal file
@@ -0,0 +1,460 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
|
||||
org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
|
||||
org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
|
||||
org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
|
||||
org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=16
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=16
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=error
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
|
||||
org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.release=enabled
|
||||
org.eclipse.jdt.core.compiler.source=16
|
||||
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_variable_declarations_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_with_spaces=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_additive_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_bitwise_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_loops=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression_chain=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=48
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_for_loop_header=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_logical_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_module_statements=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiplicative_operator=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameterized_type_references=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_relational_operator=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_shift_operator=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_string_concatenation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_type_arguments=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_type_parameters=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=next_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=next_line
|
||||
org.eclipse.jdt.core.formatter.comment.align_tags_descriptions_grouped=false
|
||||
org.eclipse.jdt.core.formatter.comment.align_tags_names_descriptions=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.count_line_length_from_starting_position=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=false
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_tag_description=false
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=120
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_additive_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_arrow_in_switch_default=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_bitwise_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_switch_case_expressions=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_logical_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_multiplicative_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_relational_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_shift_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_string_concatenation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_additive_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_arrow_in_switch_default=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_bitwise_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_switch_case_expressions=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_logical_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_multiplicative_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_relational_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_shift_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_string_concatenation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_annotation_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_anonymous_type_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_code_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_enum_constant_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_enum_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_if_then_body_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_lambda_body_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_loop_body_block_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_method_body_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.keep_simple_do_while_body_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_simple_for_body_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_simple_getter_setter_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_simple_while_body_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_type_declaration_on_one_line=one_line_never
|
||||
org.eclipse.jdt.core.formatter.lineSplit=120
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_annotation=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_catch_clause=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_enum_constant_declaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_for_statment=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_if_while_statement=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_lambda_declaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_delcaration=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_method_invocation=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_switch_statement=common_lines
|
||||
org.eclipse.jdt.core.formatter.parentheses_positions_in_try_clause=common_lines
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=3
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=true
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_additive_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_assignment_operator=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_bitwise_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_conditional_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_logical_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_multiplicative_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_relational_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_shift_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_string_concatenation=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
|
||||
63
.settings/org.eclipse.jdt.ui.prefs
Normal file
63
.settings/org.eclipse.jdt.ui.prefs
Normal file
@@ -0,0 +1,63 @@
|
||||
eclipse.preferences.version=1
|
||||
editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
|
||||
formatter_profile=_NobesFormat-2019Aug
|
||||
formatter_settings_version=16
|
||||
sp_cleanup.add_default_serial_version_id=true
|
||||
sp_cleanup.add_generated_serial_version_id=false
|
||||
sp_cleanup.add_missing_annotations=true
|
||||
sp_cleanup.add_missing_deprecated_annotations=true
|
||||
sp_cleanup.add_missing_methods=false
|
||||
sp_cleanup.add_missing_nls_tags=false
|
||||
sp_cleanup.add_missing_override_annotations=true
|
||||
sp_cleanup.add_missing_override_annotations_interface_methods=true
|
||||
sp_cleanup.add_serial_version_id=false
|
||||
sp_cleanup.always_use_blocks=true
|
||||
sp_cleanup.always_use_parentheses_in_expressions=false
|
||||
sp_cleanup.always_use_this_for_non_static_field_access=false
|
||||
sp_cleanup.always_use_this_for_non_static_method_access=false
|
||||
sp_cleanup.convert_functional_interfaces=false
|
||||
sp_cleanup.convert_to_enhanced_for_loop=false
|
||||
sp_cleanup.correct_indentation=false
|
||||
sp_cleanup.format_source_code=false
|
||||
sp_cleanup.format_source_code_changes_only=false
|
||||
sp_cleanup.insert_inferred_type_arguments=false
|
||||
sp_cleanup.make_local_variable_final=true
|
||||
sp_cleanup.make_parameters_final=false
|
||||
sp_cleanup.make_private_fields_final=true
|
||||
sp_cleanup.make_type_abstract_if_missing_method=false
|
||||
sp_cleanup.make_variable_declarations_final=false
|
||||
sp_cleanup.never_use_blocks=false
|
||||
sp_cleanup.never_use_parentheses_in_expressions=true
|
||||
sp_cleanup.on_save_use_additional_actions=true
|
||||
sp_cleanup.organize_imports=true
|
||||
sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
|
||||
sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
|
||||
sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
|
||||
sp_cleanup.remove_private_constructors=true
|
||||
sp_cleanup.remove_redundant_modifiers=false
|
||||
sp_cleanup.remove_redundant_semicolons=false
|
||||
sp_cleanup.remove_redundant_type_arguments=false
|
||||
sp_cleanup.remove_trailing_whitespaces=true
|
||||
sp_cleanup.remove_trailing_whitespaces_all=true
|
||||
sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
|
||||
sp_cleanup.remove_unnecessary_casts=true
|
||||
sp_cleanup.remove_unnecessary_nls_tags=false
|
||||
sp_cleanup.remove_unused_imports=false
|
||||
sp_cleanup.remove_unused_local_variables=false
|
||||
sp_cleanup.remove_unused_private_fields=true
|
||||
sp_cleanup.remove_unused_private_members=false
|
||||
sp_cleanup.remove_unused_private_methods=true
|
||||
sp_cleanup.remove_unused_private_types=true
|
||||
sp_cleanup.sort_members=false
|
||||
sp_cleanup.sort_members_all=false
|
||||
sp_cleanup.use_anonymous_class_creation=false
|
||||
sp_cleanup.use_blocks=false
|
||||
sp_cleanup.use_blocks_only_for_return_and_throw=false
|
||||
sp_cleanup.use_lambda=true
|
||||
sp_cleanup.use_parentheses_in_expressions=false
|
||||
sp_cleanup.use_this_for_non_static_field_access=false
|
||||
sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
|
||||
sp_cleanup.use_this_for_non_static_method_access=false
|
||||
sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
|
||||
202
LICENSE
Normal file
202
LICENSE
Normal file
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
50
README.md
Normal file
50
README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# GLUM: Great Library of User Modules
|
||||
|
||||
|
||||
## Description
|
||||
GLUM is a Java library that provides a collection of generic components, modules, and utilities which aid in development of Java software applications.
|
||||
|
||||
It provides the following high level capabilities:
|
||||
|
||||
- various components and utilities to simplify the development (creation, layout, organization, setup) of a Swing based user interface (UI)
|
||||
|
||||
- a data model focused framework for the display, editing, filtering, and searching of tabular data
|
||||
|
||||
- capability to monitor, query, or alter a “task” (mechanism to allow an end user to get information, track progress, and abort a process)
|
||||
|
||||
- serialization mechanism for saving and loading of application state
|
||||
|
||||
- capability to configure the output of data values (numeric, textual, date/time, etc)
|
||||
|
||||
- framework to allow retrieval (start, pause, resume) and management of data (local and/or remote) resources
|
||||
|
||||
|
||||
## Usage
|
||||
The latest release of GLUM is 2.0.0 and is distributed as a binary jar (glum-2.0.0.jar) and the corresponding source jar (glum-2.0.0-src.jar). These will need to be added to your class path.
|
||||
|
||||
It is intended that support via Maven mechanism will be provided in a future release.
|
||||
|
||||
|
||||
## Dependencies
|
||||
The GLUM library has the following (linking) dependencies utilized while developing the GLUM library:
|
||||
|
||||
- Java 17
|
||||
- Guava: 18.0
|
||||
- MigLayout: 3.7.2
|
||||
- DockingFrames: 1.1.3
|
||||
|
||||
In addition, to compile GLUM the following software packages are needed:
|
||||
|
||||
- JDK 17+
|
||||
- Python 3.6+
|
||||
- Apache Ant 1.10.8+
|
||||
|
||||
Note the following:
|
||||
|
||||
- In theory GLUM should work with later versions of the above listed software, but these were the ones utilized during the primary development phase.
|
||||
- The DockingFrames dependency is only necessary if gui docking capabilities are desired.
|
||||
|
||||
## Building GLUM
|
||||
To build GLUM from the console, run the following command:
|
||||
|
||||
./tools/buildRelease
|
||||
BIN
release/glum-2.0.0-src.jar
Normal file
BIN
release/glum-2.0.0-src.jar
Normal file
Binary file not shown.
BIN
release/glum-2.0.0.jar
Normal file
BIN
release/glum-2.0.0.jar
Normal file
Binary file not shown.
32
src/glum/app/AppGlum.java
Normal file
32
src/glum/app/AppGlum.java
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.app;
|
||||
|
||||
/**
|
||||
* Provides the main entry point.
|
||||
* <p>
|
||||
* Currently this will just print the library name and the version.
|
||||
*/
|
||||
public class AppGlum
|
||||
{
|
||||
/**
|
||||
* Main entry point that will print out the version of Glum to stdout.
|
||||
*/
|
||||
public static void main(String[] aArgArr)
|
||||
{
|
||||
System.out.println("Glum Library. Version: " + AppInfo.getVersion());
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
39
src/glum/app/AppInfo.java
Normal file
39
src/glum/app/AppInfo.java
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.app;
|
||||
|
||||
/**
|
||||
* Immutable class that provides information related to the build.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class AppInfo
|
||||
{
|
||||
/**
|
||||
* Defines the version of the Glum library.
|
||||
* <p>
|
||||
* Note we do not make the Version directly visible and final so other classes will not utilized a cached version
|
||||
* when built via Ant.
|
||||
*/
|
||||
private static String Version = "2.0.0";
|
||||
|
||||
/**
|
||||
* Returns the version of the application
|
||||
*/
|
||||
public static String getVersion()
|
||||
{
|
||||
return Version;
|
||||
}
|
||||
|
||||
}
|
||||
121
src/glum/color/ColorHSBL.java
Normal file
121
src/glum/color/ColorHSBL.java
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.color;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
/**
|
||||
* Immutable object which provides access to attributes of a color.
|
||||
* <p>
|
||||
* The attributes are: hue, saturation, brightness, luminance
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class ColorHSBL
|
||||
{
|
||||
// Attributes
|
||||
private final Color refColor;
|
||||
private final float hue;
|
||||
private final float saturation;
|
||||
private final float brightness;
|
||||
private final float luminance;
|
||||
|
||||
/** Standard Constructor */
|
||||
public ColorHSBL(Color aColor)
|
||||
{
|
||||
refColor = aColor;
|
||||
|
||||
float[] tmpArr = convertColorToHSBL(aColor);
|
||||
hue = tmpArr[0];
|
||||
saturation = tmpArr[1];
|
||||
brightness = tmpArr[2];
|
||||
luminance = tmpArr[3];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the associated {@link Color}.
|
||||
*/
|
||||
public Color getColor()
|
||||
{
|
||||
return refColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hue component.
|
||||
*/
|
||||
public float getHue()
|
||||
{
|
||||
return hue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the saturation component.
|
||||
*/
|
||||
public float getSaturation()
|
||||
{
|
||||
return saturation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the brightness component.
|
||||
*/
|
||||
public float getBrightness()
|
||||
{
|
||||
return brightness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the luminance component.
|
||||
*/
|
||||
public float getLuminance()
|
||||
{
|
||||
return luminance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns a 4 element array that has the following in the elements
|
||||
* <ul>
|
||||
* <li>hue
|
||||
* <li>saturation
|
||||
* <li>brightness
|
||||
* <li>luminosity
|
||||
* </ul>
|
||||
* The source for this conversion originated from:</br>
|
||||
* https://stackoverflow.com/questions/596216/formula-to-determine-perceived-brightness-of-rgb-color
|
||||
* <p>
|
||||
* Note the above source has changed overtime and the conversion below is not authoritative.
|
||||
*/
|
||||
public static float[] convertColorToHSBL(Color aColor)
|
||||
{
|
||||
int rI = aColor.getRed();
|
||||
int gI = aColor.getGreen();
|
||||
int bI = aColor.getBlue();
|
||||
|
||||
float rF = rI / 255.0f;
|
||||
float gF = gI / 255.0f;
|
||||
float bF = bI / 255.0f;
|
||||
// Formula: broken
|
||||
// float lum = (float) Math.sqrt(0.241f * rF + 0.691f * gF + 0.068f * bF);
|
||||
// Formula: corrected
|
||||
// float lum = (0.299f * rF + 0.587f * gF + 0.114f * bF);
|
||||
float lum = (float) Math.sqrt(0.299f * rF * rF + 0.587f * gF * gF + 0.114f * bF * bF);
|
||||
|
||||
float[] hsblArr = new float[4];
|
||||
Color.RGBtoHSB(rI, gI, bI, hsblArr);
|
||||
|
||||
hsblArr[3] = lum;
|
||||
return hsblArr;
|
||||
}
|
||||
|
||||
}
|
||||
125
src/glum/color/ColorHSBLCompartor.java
Normal file
125
src/glum/color/ColorHSBLCompartor.java
Normal file
@@ -0,0 +1,125 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.color;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Flexible Color Comparator that provides color comparisons using any combination of the attributes HLSB (hue, lumance,
|
||||
* saturation, brightness) rather than RGB (red,green, blue).
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class ColorHSBLCompartor implements Comparator<ColorHSBL>
|
||||
{
|
||||
// Constants
|
||||
private static ImmutableList<KeyAttr> SortKey_HLB = ImmutableList.of(KeyAttr.Hue, KeyAttr.Luminance,
|
||||
KeyAttr.Brightness);
|
||||
|
||||
// Attributes
|
||||
private final List<KeyAttr> keyL;
|
||||
private final int numGroups;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aKeyL
|
||||
* Defines an ordered list of {@link KeyAttr}s that will define how colors are sorted.
|
||||
* @param aNumGroups
|
||||
* Defines the number of groups for which the various color attributes will be grouped to.
|
||||
*/
|
||||
public ColorHSBLCompartor(List<KeyAttr> aKeyL, int aNumGroups)
|
||||
{
|
||||
keyL = ImmutableList.copyOf(aKeyL);
|
||||
numGroups = aNumGroups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified Constructor
|
||||
*
|
||||
* Colors will be sorted by the following ordered attributes: hue, lumance, and brightness.
|
||||
*
|
||||
* @param aNumGroups
|
||||
* Defines the number of groups for which the various color attributes will be grouped to.
|
||||
*/
|
||||
public ColorHSBLCompartor(int aNumGroups)
|
||||
{
|
||||
this(SortKey_HLB, aNumGroups);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(ColorHSBL aHsbl1, ColorHSBL aHsbl2)
|
||||
{
|
||||
int prevStep = 0;
|
||||
|
||||
// Iterate through all of the keys
|
||||
int tmpIdx = -1;
|
||||
for (KeyAttr aKey : keyL)
|
||||
{
|
||||
tmpIdx++;
|
||||
double fVal1, fVal2;
|
||||
switch (aKey)
|
||||
{
|
||||
case Hue:
|
||||
fVal1 = aHsbl1.getHue();
|
||||
fVal2 = aHsbl2.getHue();
|
||||
break;
|
||||
case Saturation:
|
||||
fVal1 = aHsbl1.getSaturation();
|
||||
fVal2 = aHsbl2.getSaturation();
|
||||
break;
|
||||
case Brightness:
|
||||
fVal1 = aHsbl1.getBrightness();
|
||||
fVal2 = aHsbl2.getBrightness();
|
||||
break;
|
||||
case Luminance:
|
||||
fVal1 = aHsbl1.getLuminance();
|
||||
fVal2 = aHsbl2.getLuminance();
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unrecognized key: " + aKey);
|
||||
}
|
||||
|
||||
// Compare the corresponding normalized (group) values
|
||||
int iVal1 = (int) (fVal1 * numGroups);
|
||||
int iVal2 = (int) (fVal2 * numGroups);
|
||||
int cmpVal = Integer.compare(iVal1, iVal2);
|
||||
|
||||
// If we are at the last key - do not use the normalize (group) values
|
||||
// but rather utilize the non-normalized raw float values so as to
|
||||
// reduce (eliminate?) ambiguities due to values being in the same bin.
|
||||
if (tmpIdx == keyL.size() - 1)
|
||||
cmpVal = Double.compare(fVal1, fVal2);
|
||||
|
||||
// Note we flip the comparison if the previous (key) comparison
|
||||
// resulted in an odd value. We do this so that rather than having
|
||||
// a number of step function we get more of an oscillating smooth
|
||||
// transition between the comparison keys.
|
||||
if (prevStep % 2 == 1)
|
||||
cmpVal = -cmpVal;
|
||||
|
||||
if (cmpVal != 0)
|
||||
return cmpVal;
|
||||
|
||||
prevStep = iVal1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
261
src/glum/color/ColorTestApp.java
Normal file
261
src/glum/color/ColorTestApp.java
Normal file
@@ -0,0 +1,261 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.color;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import glum.gui.misc.BooleanCellEditor;
|
||||
import glum.gui.misc.BooleanCellRenderer;
|
||||
import glum.gui.panel.itemList.*;
|
||||
import glum.gui.panel.itemList.query.QueryComposer;
|
||||
import glum.gui.table.ColorHSBLCellRenderer;
|
||||
import glum.gui.table.PrePendRenderer;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* Demo application that demonstrates a number of features:
|
||||
* <ul>
|
||||
* <li>Showing color attributes via a table
|
||||
* <li>Alternative color sorting
|
||||
* <li>Multicolmun sorting
|
||||
* </ul>
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class ColorTestApp
|
||||
{
|
||||
// Constants
|
||||
private static final int DefNumGroups = 8;
|
||||
// private static final int DefNumItems = 100; // 3100
|
||||
private static final int DefNumItems = 3100;
|
||||
|
||||
/**
|
||||
* Main entry point.
|
||||
*/
|
||||
public static void main(String[] args)
|
||||
{
|
||||
JFrame frame = new JFrame("TableColorTest");
|
||||
frame.setContentPane(formTestPanel(DefNumGroups, DefNumItems));
|
||||
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
}
|
||||
|
||||
private static JPanel formTestPanel(int aNumGroups, int aNumItems)
|
||||
{
|
||||
ItemListPanel<TestItem, LookUp> tmpILP;
|
||||
|
||||
JPanel retPanel = new JPanel(new MigLayout());
|
||||
|
||||
// Table Content
|
||||
QueryComposer<LookUp> tmpComposer = new QueryComposer<>();
|
||||
tmpComposer.addAttribute(LookUp.IsVisible, Boolean.class, "Show", 50);
|
||||
tmpComposer.addAttribute(LookUp.Index, Integer.class, "ID", "Trk: 99");
|
||||
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "HBL", 50);
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "HLB", 50);
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "HLS", 50);
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "HSB", 50);
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "HSL", 50);
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "SBH", 50);
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "SBL", 50);
|
||||
tmpComposer.addAttribute(LookUp.HSBL, Color.class, "SLB", 50);
|
||||
|
||||
tmpComposer.addAttribute(LookUp.Message, String.class, "Message", null);
|
||||
tmpComposer.addAttribute(LookUp.Red, Integer.class, "Red", 40);
|
||||
tmpComposer.addAttribute(LookUp.Green, Integer.class, "Green", 40);
|
||||
tmpComposer.addAttribute(LookUp.Blue, Integer.class, "Blue", 40);
|
||||
tmpComposer.addAttribute(LookUp.Hue, Integer.class, "Hue:" + aNumGroups, 60);
|
||||
tmpComposer.addAttribute(LookUp.Sat, Integer.class, "Sat:" + aNumGroups, 60);
|
||||
tmpComposer.addAttribute(LookUp.Lum, Integer.class, "Lum:" + aNumGroups, 60);
|
||||
tmpComposer.addAttribute(LookUp.Bri, Integer.class, "Bri:" + aNumGroups, 60);
|
||||
|
||||
tmpComposer.setEditor(LookUp.IsVisible, new BooleanCellEditor());
|
||||
tmpComposer.setRenderer(LookUp.IsVisible, new BooleanCellRenderer());
|
||||
tmpComposer.setRenderer(LookUp.Index, new PrePendRenderer("Trk: "));
|
||||
tmpComposer.setRenderer(LookUp.HSBL, new ColorHSBLCellRenderer(false));
|
||||
|
||||
// KeyType[] sortKeyArr = {KeyType.Hue, KeyType.Saturation, KeyType.Luminance};
|
||||
List<KeyAttr> sortKeyL_HBL = ImmutableList.of(KeyAttr.Hue, KeyAttr.Brightness, KeyAttr.Luminance);
|
||||
List<KeyAttr> sortKeyL_HLB = ImmutableList.of(KeyAttr.Hue, KeyAttr.Luminance, KeyAttr.Brightness);
|
||||
List<KeyAttr> sortKeyL_HLS = ImmutableList.of(KeyAttr.Hue, KeyAttr.Luminance, KeyAttr.Saturation);
|
||||
List<KeyAttr> sortKeyL_HSB = ImmutableList.of(KeyAttr.Hue, KeyAttr.Saturation, KeyAttr.Brightness);
|
||||
List<KeyAttr> sortKeyL_HSL = ImmutableList.of(KeyAttr.Hue, KeyAttr.Saturation, KeyAttr.Luminance);
|
||||
List<KeyAttr> sortKeyL_SBH = ImmutableList.of(KeyAttr.Saturation, KeyAttr.Brightness, KeyAttr.Hue);
|
||||
List<KeyAttr> sortKeyL_SBL = ImmutableList.of(KeyAttr.Saturation, KeyAttr.Brightness, KeyAttr.Luminance);
|
||||
List<KeyAttr> sortKeyL_SLB = ImmutableList.of(KeyAttr.Saturation, KeyAttr.Luminance, KeyAttr.Brightness);
|
||||
|
||||
ItemHandler<TestItem, LookUp> tmpIH = new TestItemHandler(aNumGroups);
|
||||
StaticItemProcessor<TestItem> tmpIP = new StaticItemProcessor<>(formTestItemList(aNumItems));
|
||||
tmpILP = new ItemListPanel<>(tmpIH, tmpIP, tmpComposer, true);
|
||||
tmpILP.setSortingEnabled(true);
|
||||
// tmpILP.setSortComparator(ColorHSBL.class, new ColorStepSortCompartor(numGroups));
|
||||
tmpILP.setSortComparator(2, new ColorHSBLCompartor(sortKeyL_HBL, aNumGroups));
|
||||
tmpILP.setSortComparator(3, new ColorHSBLCompartor(sortKeyL_HLB, aNumGroups));
|
||||
tmpILP.setSortComparator(4, new ColorHSBLCompartor(sortKeyL_HLS, aNumGroups));
|
||||
tmpILP.setSortComparator(5, new ColorHSBLCompartor(sortKeyL_HSB, aNumGroups));
|
||||
tmpILP.setSortComparator(6, new ColorHSBLCompartor(sortKeyL_HSL, aNumGroups));
|
||||
tmpILP.setSortComparator(7, new ColorHSBLCompartor(sortKeyL_SBH, aNumGroups));
|
||||
tmpILP.setSortComparator(8, new ColorHSBLCompartor(sortKeyL_SBL, aNumGroups));
|
||||
tmpILP.setSortComparator(9, new ColorHSBLCompartor(sortKeyL_SLB, aNumGroups));
|
||||
|
||||
// JTable tmpTable = lidarILP.getTable();
|
||||
// tmpTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
|
||||
// retPanel.add(new JScrollPane(tmpTable), "growx,growy,pushx,pushy,span,wrap");
|
||||
retPanel.add(tmpILP, "growx,growy,pushx,pushy,span,wrap");
|
||||
|
||||
tmpIP.setItems(formTestItemList(aNumItems));
|
||||
|
||||
return retPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that forms the list of TestItems.
|
||||
*/
|
||||
private static List<TestItem> formTestItemList(int aNumItems)
|
||||
{
|
||||
List<TestItem> retL = new ArrayList<>();
|
||||
|
||||
Random tmpRandom = new Random(100);
|
||||
for (int c1 = 0; c1 < aNumItems; c1++)
|
||||
{
|
||||
int r = tmpRandom.nextInt(256);
|
||||
int g = tmpRandom.nextInt(256);
|
||||
int b = tmpRandom.nextInt(256);
|
||||
Color tmpColor = new Color(r, g, b);
|
||||
String tmpMsg = String.format("Color: %3d %3d %3d", r, g, b);
|
||||
retL.add(new TestItem(c1, tmpColor, tmpMsg));
|
||||
}
|
||||
|
||||
return retL;
|
||||
}
|
||||
|
||||
enum LookUp
|
||||
{
|
||||
IsVisible,
|
||||
|
||||
Index,
|
||||
|
||||
Color,
|
||||
|
||||
HSBL,
|
||||
|
||||
Message,
|
||||
|
||||
Red,
|
||||
|
||||
Green,
|
||||
|
||||
Blue,
|
||||
|
||||
Hue,
|
||||
|
||||
Sat,
|
||||
|
||||
Lum,
|
||||
|
||||
Bri
|
||||
}
|
||||
|
||||
static class TestItem
|
||||
{
|
||||
// Attributes
|
||||
private final int index;
|
||||
private final Color color;
|
||||
private final String message;
|
||||
|
||||
// Cache vars
|
||||
private final ColorHSBL cHSBL;
|
||||
|
||||
// State vars
|
||||
private boolean isVisible;
|
||||
|
||||
public TestItem(int aIndex, Color aColor, String aMessage)
|
||||
{
|
||||
index = aIndex;
|
||||
color = aColor;
|
||||
message = aMessage;
|
||||
|
||||
cHSBL = new ColorHSBL(color);
|
||||
|
||||
isVisible = true;
|
||||
}
|
||||
}
|
||||
|
||||
static class TestItemHandler implements ItemHandler<TestItem, LookUp>
|
||||
{
|
||||
// Attributes
|
||||
private final int numGroups;
|
||||
|
||||
/** Standard Constructor */
|
||||
public TestItemHandler(int aNumGroups)
|
||||
{
|
||||
numGroups = aNumGroups;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getValue(TestItem aItem, LookUp aEnum)
|
||||
{
|
||||
switch (aEnum)
|
||||
{
|
||||
case IsVisible:
|
||||
return aItem.isVisible;
|
||||
case Index:
|
||||
return aItem.index;
|
||||
case Color:
|
||||
return aItem.color;
|
||||
case HSBL:
|
||||
return aItem.cHSBL;
|
||||
case Message:
|
||||
return aItem.message;
|
||||
case Red:
|
||||
return aItem.color.getRed();
|
||||
case Green:
|
||||
return aItem.color.getGreen();
|
||||
case Blue:
|
||||
return aItem.color.getBlue();
|
||||
case Hue:
|
||||
return (int) (aItem.cHSBL.getHue() * numGroups);
|
||||
case Sat:
|
||||
return (int) (aItem.cHSBL.getSaturation() * numGroups);
|
||||
case Bri:
|
||||
return (int) (aItem.cHSBL.getBrightness() * numGroups);
|
||||
case Lum:
|
||||
return (int) (aItem.cHSBL.getLuminance() * numGroups);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
throw new UnsupportedOperationException("Column is not supported. Enum: " + aEnum);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValue(TestItem aItem, LookUp aEnum, Object aValue)
|
||||
{
|
||||
if (aEnum == LookUp.IsVisible)
|
||||
aItem.isVisible = (Boolean) aValue;
|
||||
else
|
||||
throw new UnsupportedOperationException("Column is not supported. Enum: " + aEnum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
31
src/glum/color/KeyAttr.java
Normal file
31
src/glum/color/KeyAttr.java
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.color;
|
||||
|
||||
/**
|
||||
* Enum that defines the different attributes associated with Colors.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public enum KeyAttr
|
||||
{
|
||||
Hue,
|
||||
|
||||
Saturation,
|
||||
|
||||
Brightness,
|
||||
|
||||
Luminance,
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
/**
|
||||
* Contains conversion multipliers to/from feet, yards, meters, data miles, and nautical miles, as well as angular
|
||||
* values to/from degrees and radians. To convert a value <code>X</code> in units of <code>U</code> to units of
|
||||
* <code>V</code>, use <code>X * Convert.U_TO_V</code>.
|
||||
*/
|
||||
public class Convert
|
||||
{
|
||||
public static final double FEET_TO_METERS = 0.3048;
|
||||
public static final double DM_TO_METERS = 1828.8;
|
||||
public static final double NM_TO_METERS = 1852.0;
|
||||
public static final double MILES_TO_METERS = 1609.344;
|
||||
public static final double YARDS_TO_METERS = 0.9144; // 3 * FEET_TO_METERS
|
||||
|
||||
public static final double METERS_TO_FEET = 1.0 / FEET_TO_METERS;
|
||||
public static final double DM_TO_FEET = 6000.0;
|
||||
public static final double NM_TO_FEET = NM_TO_METERS * METERS_TO_FEET;
|
||||
public static final double MILES_TO_FEET = 5280.0;
|
||||
public static final double YARDS_TO_FEET = 3.0;
|
||||
|
||||
public static final double METERS_TO_DM = 1.0 / DM_TO_METERS;
|
||||
public static final double FEET_TO_DM = FEET_TO_METERS * METERS_TO_DM;
|
||||
public static final double NM_TO_DM = NM_TO_METERS * METERS_TO_DM;
|
||||
public static final double MILES_TO_DM = MILES_TO_METERS * METERS_TO_DM;
|
||||
public static final double YARDS_TO_DM = YARDS_TO_METERS * METERS_TO_DM;
|
||||
|
||||
public static final double METERS_TO_NM = 1.0 / NM_TO_METERS;
|
||||
public static final double FEET_TO_NM = FEET_TO_METERS * METERS_TO_NM;
|
||||
public static final double DM_TO_NM = DM_TO_METERS * METERS_TO_NM;
|
||||
public static final double MILES_TO_NM = MILES_TO_METERS * METERS_TO_NM;
|
||||
public static final double YARDS_TO_NM = YARDS_TO_METERS * NM_TO_METERS;
|
||||
|
||||
public static final double METERS_TO_MILES = 1.0 / MILES_TO_METERS;
|
||||
public static final double FEET_TO_MILES = FEET_TO_METERS * METERS_TO_MILES;
|
||||
public static final double DM_TO_MILES = DM_TO_METERS * METERS_TO_MILES;
|
||||
public static final double NM_TO_MILES = NM_TO_METERS * METERS_TO_MILES;
|
||||
public static final double YARDS_TO_MILES = YARDS_TO_METERS * METERS_TO_MILES;
|
||||
|
||||
public static final double METERS_TO_YARDS = 1.0 / YARDS_TO_METERS;
|
||||
public static final double FEET_TO_YARDS = 1.0 / 3.0;
|
||||
public static final double DM_TO_YARDS = 2000.0;
|
||||
public static final double NM_TO_YARDS = NM_TO_METERS * METERS_TO_YARDS;
|
||||
public static final double MILES_TO_YARDS = 1760.0;
|
||||
|
||||
public static final double RAD_TO_DEG = 180.0 / Math.PI;
|
||||
public static final double DEG_TO_RAD = Math.PI / 180.0;
|
||||
|
||||
public static final double SECS_TO_MSECS = 1000.0;
|
||||
public static final double MSECS_TO_SECS = 1.0 / SECS_TO_MSECS;
|
||||
|
||||
public static final int MINS_TO_SECS = 60;
|
||||
public static final int HOURS_TO_MINS = 60;
|
||||
public static final int HOURS_TO_SECS = HOURS_TO_MINS * MINS_TO_SECS;
|
||||
|
||||
public static final double SECS_TO_MINS = 1 / MINS_TO_SECS;
|
||||
public static final double MINS_TO_HOURS = 1 / HOURS_TO_MINS;
|
||||
public static final double SECS_TO_HOURS = 1 / HOURS_TO_SECS;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
private Convert()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an angle to a bearing
|
||||
*/
|
||||
public static double angleToBearing(double aAngle)
|
||||
{
|
||||
double bearing;
|
||||
|
||||
bearing = 180 - (aAngle + 90);
|
||||
if (bearing < 0)
|
||||
bearing += 360;
|
||||
|
||||
return bearing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a bearing to an angle
|
||||
*/
|
||||
public static double bearingToAngle(double aBearing)
|
||||
{
|
||||
double angle;
|
||||
|
||||
angle = 180 - (aBearing + 90);
|
||||
if (angle < 0)
|
||||
angle += 360;
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
|
||||
/** Provides a few useful functions on coordinates, such as converting
|
||||
* to a user-presentable string.
|
||||
*/
|
||||
public class CoordUtil
|
||||
{
|
||||
/** Convert a Lat/Lon to a pair of DEG:MM:SS H strings. H is the
|
||||
* hemisphere, N or S for lat, E or W for lon. The default separator
|
||||
* string LL_SEP is used.
|
||||
*/
|
||||
public static String LatLonToString (LatLon ll)
|
||||
{
|
||||
return ll == null ? "" : LatLonToString (ll, LL_SEP);
|
||||
}
|
||||
|
||||
/** Same as the other LatLonToString, excepts this one uses the
|
||||
* given <code>sep</code> string to separate the Lat and Lon.
|
||||
*/
|
||||
public static String LatLonToString (LatLon ll, String sep)
|
||||
{
|
||||
return ll == null ? "" :
|
||||
LatToString (ll.lat) + LL_SEP + LonToString (ll.lon);
|
||||
}
|
||||
|
||||
/** Converts the given <code>lat</code> to DD:MM:SS H. */
|
||||
|
||||
public static String LatToString (double lat)
|
||||
{
|
||||
return LatToString (lat, true);
|
||||
}
|
||||
|
||||
/** Converts the given <code>lat</code> to DD:MM:SS H if
|
||||
* <code>include_seconds</code> is true. If it's false, then the
|
||||
* :SS part is left off.
|
||||
*/
|
||||
|
||||
public static String LatToString (double lat, boolean include_seconds)
|
||||
{
|
||||
DMS dms = new DMS (lat);
|
||||
StringBuffer s = new StringBuffer();
|
||||
|
||||
if ( dms.degrees < 10 )
|
||||
s.append ("0");
|
||||
s.append (dms.degrees);
|
||||
s.append (":");
|
||||
if ( dms.minutes < 10 )
|
||||
s.append ("0");
|
||||
s.append (dms.minutes);
|
||||
if ( include_seconds )
|
||||
{
|
||||
s.append (":");
|
||||
if ( dms.seconds < 10 )
|
||||
s.append ("0");
|
||||
s.append (dms.seconds);
|
||||
}
|
||||
s.append (lat >= 0 ? " N" : " S");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
/** Similar to <code>LatToString</code> except that the degrees
|
||||
* part is DDD instead of DD. */
|
||||
|
||||
public static String LonToString (double lon)
|
||||
{
|
||||
return LonToString (lon, true);
|
||||
}
|
||||
|
||||
/** Similar to <code>LatToString</code> except that the degrees
|
||||
* part is DDD instead of DD. */
|
||||
|
||||
public static String LonToString (double lon, boolean include_seconds)
|
||||
{
|
||||
DMS dms = new DMS (lon);
|
||||
StringBuffer s = new StringBuffer();
|
||||
|
||||
if ( dms.degrees < 100 )
|
||||
s.append ("0");
|
||||
if ( dms.degrees < 10 )
|
||||
s.append ("0");
|
||||
s.append (dms.degrees);
|
||||
s.append (":");
|
||||
if ( dms.minutes < 10 )
|
||||
s.append ("0");
|
||||
s.append (dms.minutes);
|
||||
if ( include_seconds )
|
||||
{
|
||||
s.append (":");
|
||||
if ( dms.seconds < 10 )
|
||||
s.append ("0");
|
||||
s.append (dms.seconds);
|
||||
}
|
||||
s.append (lon >= 0 ? " E" : " W");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
/** Converts <code>dmsh_string</code> to a double value.
|
||||
* The string format should match the output of the
|
||||
* LatToString formats, including hemisphere.
|
||||
* If a hemisphere character is not part of the string, the
|
||||
* returned value will be non-negative.
|
||||
*/
|
||||
public static double StringToLat (String dmsh_string)
|
||||
{
|
||||
if ( dmsh_string == null || dmsh_string.length() == 0 )
|
||||
return 0.0;
|
||||
|
||||
int dms [] = StringToDMS (dmsh_string);
|
||||
|
||||
if ( dms.length == 3 )
|
||||
return new Degrees (dms[0], dms[1], dms[2]).degrees;
|
||||
else return 0.0;
|
||||
}
|
||||
|
||||
/** {@see StringToLat} */
|
||||
|
||||
public static double StringToLon (String dmsh_string)
|
||||
{
|
||||
// Because we aren't doing any range or hemisphere error
|
||||
// checking, a lon value is identical to a lat value.
|
||||
return StringToLat (dmsh_string);
|
||||
}
|
||||
|
||||
/** Converts <code>dmsh_string</code> to a an array of
|
||||
* 3 ints representing degrees, minutes, and seconds.
|
||||
* if a hemisphere character is present (one of NSEW or
|
||||
* nsew), and it represents a souther or western hemisphere,
|
||||
* then the degrees value, in index 0 of the returned array,
|
||||
* will be a non-positive number.
|
||||
*/
|
||||
public static int [] StringToDMS (String dmsh_string)
|
||||
{
|
||||
if ( dmsh_string == null || dmsh_string.length() == 0 )
|
||||
return null;
|
||||
|
||||
char chars [] = dmsh_string.toCharArray();
|
||||
int dms [] = new int [ 3 ];
|
||||
|
||||
dms[0] = 0;
|
||||
for ( int i = 0, j = 0; i < chars.length; i++ )
|
||||
{
|
||||
char c = chars[i];
|
||||
|
||||
if ( c == ' ' || c == ' ' ) // Space or tab.
|
||||
continue;
|
||||
else if ( c >= '0' && c <= '9' && j < 3 )
|
||||
dms[j] = dms[j] * 10 + c - '0';
|
||||
else if ( c == ':' )
|
||||
{
|
||||
j++;
|
||||
dms[j] = 0;
|
||||
}
|
||||
else if ( c == 'S' || c == 's' || c == 'W' || c == 'w' )
|
||||
dms[0] = -dms[0];
|
||||
}
|
||||
|
||||
return dms;
|
||||
}
|
||||
|
||||
public static class DMS
|
||||
{
|
||||
public DMS (double deg)
|
||||
{
|
||||
if ( deg < 0 ) deg = -deg;
|
||||
degrees = (int) deg;
|
||||
minutes = (int) (deg * 60) % 60;
|
||||
seconds = (int) (deg * 3600) % 60;
|
||||
}
|
||||
public int degrees, minutes, seconds;
|
||||
}
|
||||
|
||||
public static class Degrees
|
||||
{
|
||||
public Degrees (int deg, int min, int sec)
|
||||
{
|
||||
degrees = Math.abs (deg) +
|
||||
Math.abs(min) / 60.0 +
|
||||
Math.abs(sec) / 3600.0;
|
||||
if ( deg < 0 || min < 0 || sec < 0 )
|
||||
degrees = -degrees;
|
||||
}
|
||||
public Degrees (int deg, int min, int sec, char hemisphere)
|
||||
{
|
||||
this (deg, min, sec);
|
||||
if ( hemisphere == 'N' || hemisphere == 'n' ||
|
||||
hemisphere == 'E' || hemisphere == 'e' )
|
||||
degrees = Math.abs (degrees);
|
||||
else if ( hemisphere == 'S' || hemisphere == 's' ||
|
||||
hemisphere == 'W' || hemisphere == 'w' )
|
||||
degrees = -Math.abs (degrees);
|
||||
}
|
||||
public double degrees;
|
||||
}
|
||||
|
||||
public static String LL_SEP = " / ";
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
/** Determines if two numbers are close, usually as a way to say
|
||||
* that they are equal. Close is defined to mean that their difference
|
||||
* is less than some small number, which is either supplied by the caller
|
||||
* or is EPSILON.
|
||||
* <p>For longitude near the equator, a difference of EPSILON is about
|
||||
* 3.65 feet (where the earth's circumference is about 21913.3 DM, or
|
||||
* about 60.87 DM per degree longitude). For DataMile measurements, it's
|
||||
* about 0.72 inches.
|
||||
*/
|
||||
|
||||
public class Epsilon
|
||||
{
|
||||
/** The measure of closeness; set to 0.00001. */
|
||||
public static final double EPSILON = 0.00001;
|
||||
|
||||
public static boolean close (float a, float b)
|
||||
{
|
||||
float diff = a - b;
|
||||
return diff < EPSILON && diff > -EPSILON;
|
||||
}
|
||||
|
||||
public static boolean close (float a, float b, float epsilon)
|
||||
{
|
||||
float diff = a - b;
|
||||
return diff < epsilon && diff > -epsilon;
|
||||
}
|
||||
|
||||
public static boolean close (double a, double b)
|
||||
{
|
||||
double diff = a - b;
|
||||
return diff < EPSILON && diff > -EPSILON;
|
||||
}
|
||||
|
||||
public static boolean close (double a, double b, float epsilon)
|
||||
{
|
||||
double diff = a - b;
|
||||
return diff < EPSILON && diff > -EPSILON;
|
||||
}
|
||||
|
||||
private Epsilon () { }
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
/**
|
||||
* Contains a collection of utility methods to perform linear algebra using the objects from this package.
|
||||
*/
|
||||
public class GeoUtil
|
||||
{
|
||||
/**
|
||||
* realSqr returns aNum*aNum
|
||||
*/
|
||||
public static double realSqr(double aNum)
|
||||
{
|
||||
return aNum * aNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* computeDotProduct - Returns the dot product of vector1 and vector2
|
||||
*/
|
||||
public static double computeDotProduct(Point3D vector1, Point3D vector2)
|
||||
{
|
||||
return vector1.x * vector2.x + vector1.y * vector2.y + vector1.z * vector2.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* computeDistance - Returns the distance between pt1 and pt2
|
||||
*/
|
||||
public static double computeDistance(Point3D pt1, Point3D pt2)
|
||||
{
|
||||
return Math.sqrt(realSqr(pt1.x - pt2.x) + realSqr(pt1.y - pt2.y) + realSqr(pt1.z - pt2.z));
|
||||
}
|
||||
|
||||
/**
|
||||
* computeDistanceSquare - Returns the squared distance between pt1 and pt2
|
||||
*/
|
||||
public static double computeDistanceSquare(Point3D pt1, Point3D pt2)
|
||||
{
|
||||
return realSqr(pt1.x - pt2.x) + realSqr(pt1.y - pt2.y) + realSqr(pt1.z - pt2.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* computeLength - Returns the magnitude of aVector
|
||||
*/
|
||||
public static double computeLength(Point3D aVector)
|
||||
{
|
||||
return Math.sqrt(realSqr(aVector.x) + realSqr(aVector.y) + realSqr(aVector.z));
|
||||
}
|
||||
|
||||
/**
|
||||
* computeNormal - Returns the R.H.R normal defined by the 3 points
|
||||
*/
|
||||
public static void computeNormal(Point3D pt1, Point3D pt2, Point3D pt3, Point3D aNormal)
|
||||
{
|
||||
Point3D vector1, vector2;
|
||||
|
||||
vector1 = new Point3D();
|
||||
vector2 = new Point3D();
|
||||
computeVector(pt1, pt3, vector1);
|
||||
computeVector(pt3, pt2, vector2);
|
||||
|
||||
// ! Not sure why I have to negate all the values; Need to refer to linear alg.
|
||||
//! aNormal.x = vector1.y*vector2.z - vector1.z*vector2.y;
|
||||
//! aNormal.y = vector1.z*vector2.x - vector1.x*vector2.z;
|
||||
//! aNormal.z = vector1.x*vector2.y - vector1.y*vector2.x;
|
||||
aNormal.x = -(vector1.y * vector2.z - vector1.z * vector2.y);
|
||||
aNormal.y = -(vector1.z * vector2.x - vector1.x * vector2.z);
|
||||
aNormal.z = -(vector1.x * vector2.y - vector1.y * vector2.x);
|
||||
|
||||
// Normalize the vector
|
||||
normalizeVector(aNormal);
|
||||
}
|
||||
|
||||
/**
|
||||
* computeVector - Returns the vector defined by the 2 points
|
||||
*/
|
||||
public static void computeVector(Point3D pt1, Point3D pt2, Point3D aVector)
|
||||
{
|
||||
aVector.x = pt2.x - pt1.x;
|
||||
aVector.y = pt2.y - pt1.y;
|
||||
aVector.z = pt2.z - pt1.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* normalizeVector - Normalizes aVector so that its length is 1
|
||||
*/
|
||||
public static void normalizeVector(Point3D aVector)
|
||||
{
|
||||
double length;
|
||||
|
||||
length = computeLength(aVector);
|
||||
|
||||
// Normalize the vector
|
||||
aVector.x = aVector.x / length;
|
||||
aVector.y = aVector.y / length;
|
||||
aVector.z = aVector.z / length;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
/** Simple class for Lat/Lon values. */
|
||||
public class LatLon
|
||||
{
|
||||
public double lat;
|
||||
public double lon;
|
||||
|
||||
public LatLon()
|
||||
{
|
||||
}
|
||||
|
||||
public LatLon(LatLon latlon)
|
||||
{
|
||||
if (latlon != null)
|
||||
{
|
||||
lat = latlon.lat;
|
||||
lon = latlon.lon;
|
||||
}
|
||||
}
|
||||
|
||||
public LatLon(double lat, double lon)
|
||||
{
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public LatLon(String lat_string, String lon_string)
|
||||
{
|
||||
set(lat_string, lon_string);
|
||||
}
|
||||
|
||||
public void set(double lat, double lon)
|
||||
{
|
||||
this.lat = lat;
|
||||
this.lon = lon;
|
||||
}
|
||||
|
||||
public void set(LatLon latlon)
|
||||
{
|
||||
if (latlon != null)
|
||||
{
|
||||
lat = latlon.lat;
|
||||
lon = latlon.lon;
|
||||
}
|
||||
}
|
||||
|
||||
public void set(String lat_string, String lon_string)
|
||||
{
|
||||
lat = CoordUtil.StringToLat(lat_string);
|
||||
lon = CoordUtil.StringToLon(lon_string);
|
||||
}
|
||||
|
||||
public void normalize()
|
||||
{
|
||||
if (lat > 90)
|
||||
lat = 90;
|
||||
else if (lat < -90)
|
||||
lat = -90;
|
||||
|
||||
if (lon > 180)
|
||||
lon -= 360;
|
||||
else if (lon < -180)
|
||||
lon += 360;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests to see if the given object is the same lat/lon as this position.
|
||||
* "Same" really means "very, very close," as defined by {@link Epsilon}.
|
||||
*
|
||||
* @return True if obj is a LatLon and is very close to our lat/lon position.
|
||||
* False otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
return (obj instanceof LatLon) && Epsilon.close(lat, ((LatLon)obj).lat) && Epsilon.close(lon, ((LatLon)obj).lon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return CoordUtil.LatLonToString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the change in latitude
|
||||
*/
|
||||
static public double computeDeltaLat(double lat1, double lat2)
|
||||
{
|
||||
return lat2 - lat1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the change in longitude
|
||||
*/
|
||||
static public double computeDeltaLon(double lon1, double lon2)
|
||||
{
|
||||
double dLon;
|
||||
|
||||
dLon = lon2 - lon1;
|
||||
if (Math.abs(dLon) < 180)
|
||||
return dLon;
|
||||
|
||||
if (dLon > 180)
|
||||
return dLon - 360;
|
||||
else
|
||||
return dLon + 360;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
public class Point2D
|
||||
{
|
||||
public double x;
|
||||
public double y;
|
||||
|
||||
public Point2D () { }
|
||||
|
||||
public Point2D (Point2D pt)
|
||||
{ if ( pt != null ) { x = pt.x; y = pt.y; } }
|
||||
|
||||
public Point2D (double x, double y)
|
||||
{ this.x = x; this.y = y; }
|
||||
|
||||
public void set (double x, double y)
|
||||
{ this.x = x; this.y = y; }
|
||||
|
||||
public void set (Point2D pt)
|
||||
{ if ( pt != null ) { x = pt.x; y = pt.y; } }
|
||||
|
||||
public double distance (Point2D aPt)
|
||||
{
|
||||
if (aPt == null)
|
||||
return 0;
|
||||
|
||||
return Math.sqrt((aPt.x - x)*(aPt.x - x) + (aPt.y - y)*(aPt.y - y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
return (obj instanceof Point2D) &&
|
||||
Epsilon.close (x, ((Point2D) obj).x) &&
|
||||
Epsilon.close (y, ((Point2D) obj).y);
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
public class Point2Di
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
public Point2Di () { }
|
||||
|
||||
public Point2Di (Point2Di pt)
|
||||
{ if ( pt != null ) { x = pt.x; y = pt.y; } }
|
||||
|
||||
public Point2Di (int x, int y) { this.x = x; this.y = y; }
|
||||
|
||||
public void set (int x, int y) { this.x = x; this.y = y; }
|
||||
|
||||
public void set (Point2Di pt)
|
||||
{ if ( pt != null ) { x = pt.x; y = pt.y; } }
|
||||
|
||||
@Override
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
return (obj instanceof Point2Di) &&
|
||||
x == ((Point2Di) obj).x &&
|
||||
y == ((Point2Di) obj).y;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
/** A class for representing any 3-Dimensional vector, which could be
|
||||
* a position, a velocity, or a rotation. No information about units
|
||||
* is assumed or implied.
|
||||
*/
|
||||
|
||||
public class Point3D
|
||||
{
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
|
||||
public Point3D () { }
|
||||
|
||||
public Point3D (Point3D pt)
|
||||
{ if ( pt != null ) { x = pt.x; y = pt.y; z = pt.z; } }
|
||||
|
||||
public Point3D (double x, double y, double z)
|
||||
{ this.x = x; this.y = y; this.z = z; }
|
||||
|
||||
public void set (double x, double y, double z)
|
||||
{ this.x = x; this.y = y; this.z = z; }
|
||||
|
||||
public void set (Point3D pt)
|
||||
{ if ( pt != null ) { x = pt.x; y = pt.y; z = pt.z; } }
|
||||
|
||||
@Override
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
return (obj instanceof Point3D) &&
|
||||
Epsilon.close (x, ((Point3D) obj).x) &&
|
||||
Epsilon.close (y, ((Point3D) obj).y) &&
|
||||
Epsilon.close (z, ((Point3D) obj).z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return new String("(" + x + ", " + y + ", " + z + ")");
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
public class RngBrg
|
||||
{
|
||||
public double rng;
|
||||
public double brg;
|
||||
|
||||
public RngBrg() { }
|
||||
|
||||
public RngBrg(RngBrg pt)
|
||||
{
|
||||
if ( pt != null )
|
||||
{
|
||||
rng = pt.rng;
|
||||
brg = pt.brg;
|
||||
}
|
||||
}
|
||||
|
||||
public RngBrg (double rng, double brg)
|
||||
{
|
||||
this.rng = rng;
|
||||
this.brg = brg;
|
||||
}
|
||||
|
||||
public void set (double rng, double brg)
|
||||
{
|
||||
this.rng = rng;
|
||||
this.brg = brg;
|
||||
}
|
||||
|
||||
public void set (RngBrg pt)
|
||||
{
|
||||
if ( pt != null )
|
||||
{
|
||||
rng = pt.rng;
|
||||
brg = pt.brg;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object obj)
|
||||
{
|
||||
return (obj instanceof RngBrg) &&
|
||||
Epsilon.close (rng, ((RngBrg) obj).rng) &&
|
||||
Epsilon.close (brg, ((RngBrg) obj).brg);
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package glum.coord;
|
||||
|
||||
public class UV extends Point2D
|
||||
{
|
||||
public UV ()
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
public UV (Point2D pt)
|
||||
{
|
||||
if (pt != null)
|
||||
{
|
||||
x = pt.x;
|
||||
y = pt.y;
|
||||
}
|
||||
}
|
||||
|
||||
public UV (double x, double y)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.database;
|
||||
|
||||
public abstract interface QueryItem<G1 extends Enum<?>>
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.database;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
/**
|
||||
* {@link Comparable} to sort {@link QueryItem}s based on the provided key.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class QueryItemComparator<G1 extends QueryItem<G2>, G2 extends Enum<?>> implements Comparator<G1>
|
||||
{
|
||||
private G2 sortKey;
|
||||
// Attributes
|
||||
private final G2 sortKey;
|
||||
|
||||
/** Standard Constructor */
|
||||
public QueryItemComparator(G2 aSortKey)
|
||||
{
|
||||
sortKey = aSortKey;
|
||||
@@ -15,10 +35,8 @@ public class QueryItemComparator<G1 extends QueryItem<G2>, G2 extends Enum<?>> i
|
||||
@Override
|
||||
public int compare(G1 item1, G1 item2)
|
||||
{
|
||||
Comparable<Object> value1, value2;
|
||||
|
||||
value1 = (Comparable<Object>)item1.getValue(sortKey);
|
||||
value2 = (Comparable<Object>)item2.getValue(sortKey);
|
||||
var value1 = (Comparable<Object>) item1.getValue(sortKey);
|
||||
var value2 = (Comparable<Object>) item2.getValue(sortKey);
|
||||
|
||||
if (value1 == null && value2 == null)
|
||||
return 0;
|
||||
@@ -34,29 +52,23 @@ public class QueryItemComparator<G1 extends QueryItem<G2>, G2 extends Enum<?>> i
|
||||
|
||||
/**
|
||||
* Utility method to create a QueryItemComparator by specifying the class and sort Enum.
|
||||
* <P>
|
||||
* <p>
|
||||
* This logic is here due to Java's horrible implementation off generics.
|
||||
*/
|
||||
public static <G3 extends QueryItem<G4>, G4 extends Enum<?>> Comparator<G3> spawn(Class<G3> aClass, G4 aEnum)
|
||||
{
|
||||
QueryItemComparator<G3, G4> retComparator;
|
||||
|
||||
retComparator = new QueryItemComparator<G3, G4>(aEnum);
|
||||
return retComparator;
|
||||
return new QueryItemComparator<G3, G4>(aEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to create a QueryItemComparator by specifying just the Enum. Note this method can not be used in a
|
||||
* argument to another method; instead use: {@link #spawn(Class, Enum)}
|
||||
* <P>
|
||||
* <p>
|
||||
* This logic is here due to Java's horrible implementation off generics.
|
||||
*/
|
||||
public static <G3 extends QueryItem<G4>, G4 extends Enum<?>> Comparator<G3> spawn(G4 aEnum)
|
||||
{
|
||||
QueryItemComparator<G3, G4> retComparator;
|
||||
|
||||
retComparator = new QueryItemComparator<G3, G4>(aEnum);
|
||||
return retComparator;
|
||||
return new QueryItemComparator<G3, G4>(aEnum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
101
src/glum/digest/Digest.java
Normal file
101
src/glum/digest/Digest.java
Normal file
@@ -0,0 +1,101 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.digest;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Immutable object that stores a single digest.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class Digest
|
||||
{
|
||||
private final DigestType digestType;
|
||||
private final byte[] digestValueArr;
|
||||
|
||||
public Digest(DigestType aDigestType, byte[] aDigestValueArr)
|
||||
{
|
||||
digestType = aDigestType;
|
||||
digestValueArr = Arrays.copyOf(aDigestValueArr, aDigestValueArr.length);
|
||||
}
|
||||
|
||||
public Digest(DigestType aDigestType, String aHexStr)
|
||||
{
|
||||
digestType = aDigestType;
|
||||
digestValueArr = DigestUtils.hexStr2ByteArr(aHexStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a user friendly description (string) of this digest result.
|
||||
* <p>
|
||||
* The result will be DigestType:hexDigestValue
|
||||
*/
|
||||
public String getDescr()
|
||||
{
|
||||
return "" + digestType + ":" + getValueAsString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DigestType associated with this Digest.
|
||||
*/
|
||||
public DigestType getType()
|
||||
{
|
||||
return digestType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual digest (as a string) associated with this Digest.
|
||||
*/
|
||||
public byte[] getValue()
|
||||
{
|
||||
return Arrays.copyOf(digestValueArr, digestValueArr.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the actual digest (as a string) associated with this Digest.
|
||||
*/
|
||||
public String getValueAsString()
|
||||
{
|
||||
return DigestUtils.byteArr2HexStr(digestValueArr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + ((digestType == null) ? 0 : digestType.hashCode());
|
||||
result = prime * result + Arrays.hashCode(digestValueArr);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Digest other = (Digest) obj;
|
||||
if (digestType != other.digestType)
|
||||
return false;
|
||||
if (!Arrays.equals(digestValueArr, other.digestValueArr))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
64
src/glum/digest/DigestType.java
Normal file
64
src/glum/digest/DigestType.java
Normal file
@@ -0,0 +1,64 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.digest;
|
||||
|
||||
/**
|
||||
* Enum that defines the supported digest types.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public enum DigestType
|
||||
{
|
||||
// Weak digest - but very fast
|
||||
MD5("MD5"),
|
||||
|
||||
// Fairly strong digest type (with good performance on 32 bit machines)
|
||||
SHA256("SHA-256"),
|
||||
|
||||
// Very strong digest type
|
||||
SHA512("SHA-512");
|
||||
|
||||
// State vars
|
||||
private String algName;
|
||||
|
||||
private DigestType(String aAlgName)
|
||||
{
|
||||
algName = aAlgName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the official digest algorithm name.
|
||||
*
|
||||
* @see http://docs.oracle.com/javase/1.5.0/docs/guide/security/CryptoSpec.html#AppA
|
||||
*/
|
||||
public String getAlgName()
|
||||
{
|
||||
return algName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the corresponding DigestType.
|
||||
*/
|
||||
public static DigestType parse(String aStr)
|
||||
{
|
||||
if (aStr.equalsIgnoreCase("MD5") == true)
|
||||
return MD5;
|
||||
if (aStr.equalsIgnoreCase("SHA256") == true)
|
||||
return SHA256;
|
||||
if (aStr.equalsIgnoreCase("SHA512") == true)
|
||||
return SHA512;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
83
src/glum/digest/DigestUtils.java
Normal file
83
src/glum/digest/DigestUtils.java
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.digest;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import com.google.common.io.BaseEncoding;
|
||||
|
||||
/**
|
||||
* Collection of utility methods to ease working with the MessageDigest and associated classes.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class DigestUtils
|
||||
{
|
||||
/**
|
||||
* Utility method that will throw a RuntimeExcepption if the specified digest function is not found.
|
||||
* <p>
|
||||
* Algorithm should be MD5, SHA-256, SHA-512, ...
|
||||
* <p>
|
||||
* See: http://docs.oracle.com/javase/1.8.0/docs/guide/security/CryptoSpec.html#AppA
|
||||
*/
|
||||
public static MessageDigest getDigest(String aAlgorithm)
|
||||
{
|
||||
MessageDigest retDigest;
|
||||
|
||||
try
|
||||
{
|
||||
retDigest = MessageDigest.getInstance(aAlgorithm);
|
||||
}
|
||||
catch (NoSuchAlgorithmException aExp)
|
||||
{
|
||||
throw new RuntimeException("Digest not found. Digest algorith not found: " + aAlgorithm);
|
||||
}
|
||||
|
||||
return retDigest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that will throw a RuntimeExcepption if the specified digest function is not found.
|
||||
* <p>
|
||||
* See: http://docs.oracle.com/javase/1.8.0/docs/guide/security/CryptoSpec.html#AppA
|
||||
*/
|
||||
public static MessageDigest getDigest(DigestType aDigestType)
|
||||
{
|
||||
return getDigest(aDigestType.getAlgName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns the (lower case) hex string corresponding to the byte array.
|
||||
* <p>
|
||||
* Delegates to {@link BaseEncoding.base16().lowerCase().encode(CharSequence)}
|
||||
*/
|
||||
public static String byteArr2HexStr(byte[] aByteArr)
|
||||
{
|
||||
String retStr = BaseEncoding.base16().lowerCase().encode(aByteArr);
|
||||
return retStr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns a byte array corresponding to the hex string.
|
||||
* <p>
|
||||
* Delegates to {@link BaseEncoding.base16().lowerCase().decode(CharSequence)}
|
||||
*/
|
||||
public static byte[] hexStr2ByteArr(String aHexStr)
|
||||
{
|
||||
byte[] retArr = BaseEncoding.base16().lowerCase().decode(aHexStr);
|
||||
return retArr;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,35 +1,50 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import glum.zio.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* A {@link Filter} which performs filtering based on a enam values.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*
|
||||
* @param <G1>
|
||||
*/
|
||||
public abstract class EnumFilter<G1, G2 extends Enum<?>> implements ZioObj, Filter<G1>
|
||||
{
|
||||
// Static config vars
|
||||
private Map<Integer, Enum<?>> fullMap;
|
||||
|
||||
|
||||
// State vars
|
||||
private Set<Enum<?>> validSet;
|
||||
private Set<Enum<?>> validS;
|
||||
private boolean isEnabled;
|
||||
|
||||
|
||||
/** Standard Constructor */
|
||||
public EnumFilter(Class<? extends Enum<?>> enumClass)
|
||||
{
|
||||
fullMap = Maps.newLinkedHashMap();
|
||||
fullMap = new LinkedHashMap<>();
|
||||
for (Enum<?> aEnum : enumClass.getEnumConstants())
|
||||
fullMap.put(aEnum.ordinal(), aEnum);
|
||||
|
||||
validSet = Sets.newLinkedHashSet();
|
||||
|
||||
validS = new LinkedHashSet<>();
|
||||
isEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the filter is active.
|
||||
*/
|
||||
@@ -43,7 +58,7 @@ public abstract class EnumFilter<G1, G2 extends Enum<?>> implements ZioObj, Filt
|
||||
*/
|
||||
public List<Enum<?>> getSelectedItems()
|
||||
{
|
||||
return Lists.newArrayList(validSet);
|
||||
return new ArrayList<>(validS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,10 +66,10 @@ public abstract class EnumFilter<G1, G2 extends Enum<?>> implements ZioObj, Filt
|
||||
*/
|
||||
public void set(EnumFilter<G1, G2> aFilter)
|
||||
{
|
||||
validSet = Sets.newLinkedHashSet(aFilter.validSet);
|
||||
validS = new LinkedHashSet<>(aFilter.validS);
|
||||
isEnabled = aFilter.getIsEnabled();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets whether the filter is active.
|
||||
*/
|
||||
@@ -62,57 +77,52 @@ public abstract class EnumFilter<G1, G2 extends Enum<?>> implements ZioObj, Filt
|
||||
{
|
||||
isEnabled = aBool;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the list of valid enums for this filter.
|
||||
*/
|
||||
public void setSetSelectedItems(List<Enum<?>> selectedItems)
|
||||
public void setSetSelectedItems(List<Enum<?>> aItemL)
|
||||
{
|
||||
validSet.clear();
|
||||
validSet.addAll(selectedItems);
|
||||
validS.clear();
|
||||
validS.addAll(aItemL);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void zioRead(ZinStream aStream) throws IOException
|
||||
{
|
||||
int numItems;
|
||||
|
||||
aStream.readVersion(0);
|
||||
|
||||
|
||||
// Read the payload
|
||||
isEnabled = aStream.readBool();
|
||||
|
||||
validSet.clear();
|
||||
numItems = aStream.readInt();
|
||||
|
||||
validS.clear();
|
||||
var numItems = aStream.readInt();
|
||||
for (int c1 = 0; c1 < numItems; c1++)
|
||||
validSet.add(fullMap.get(aStream.readInt()));
|
||||
validS.add(fullMap.get(aStream.readInt()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zioWrite(ZoutStream aStream) throws IOException
|
||||
{
|
||||
int numItems;
|
||||
|
||||
aStream.writeVersion(0);
|
||||
|
||||
|
||||
aStream.writeBool(isEnabled);
|
||||
|
||||
numItems = validSet.size();
|
||||
var numItems = validS.size();
|
||||
aStream.writeInt(numItems);
|
||||
for (Enum<?> aEnum : validSet)
|
||||
for (Enum<?> aEnum : validS)
|
||||
aStream.writeInt(aEnum.ordinal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns whether aValue is within the constraints
|
||||
* specified by this filter.
|
||||
* Utility method that returns whether aValue is within the constraints specified by this filter.
|
||||
*/
|
||||
protected boolean testIsValid(G2 aEnum)
|
||||
{
|
||||
if (isEnabled == false)
|
||||
return true;
|
||||
|
||||
return validSet.contains(aEnum);
|
||||
|
||||
return validS.contains(aEnum);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,7 +1,27 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.filter;
|
||||
|
||||
import glum.zio.ZioObj;
|
||||
|
||||
/**
|
||||
* Interface that provides a mechanism for filtering items.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*
|
||||
* @param <G1>
|
||||
*/
|
||||
public interface Filter<G1> extends ZioObj
|
||||
{
|
||||
/**
|
||||
|
||||
@@ -1,14 +1,31 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.filter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import glum.gui.component.GList;
|
||||
import glum.gui.component.GNumberField;
|
||||
|
||||
/**
|
||||
* Collection of utility methods used to aide with working with {@link Filter}s and (swing) UI components.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class FilterUtil
|
||||
{
|
||||
/**
|
||||
@@ -16,16 +33,14 @@ public class FilterUtil
|
||||
*/
|
||||
public static <G1> List<G1> applyFilter(List<G1> itemList, Filter<G1> aFilter)
|
||||
{
|
||||
List<G1> retList;
|
||||
|
||||
retList = Lists.newArrayList();
|
||||
var retItemL = new ArrayList<G1>();
|
||||
for (G1 aItem : itemList)
|
||||
{
|
||||
if (aFilter.isValid(aItem) == true)
|
||||
retList.add(aItem);
|
||||
retItemL.add(aItem);
|
||||
}
|
||||
|
||||
return retList;
|
||||
return retItemL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,18 +53,19 @@ public class FilterUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to synchronize the associated GUI controls with the specified filter.
|
||||
* Utility method to synchronize the associated GUI controls with the specified filter.
|
||||
*/
|
||||
public static void setEnumFilter(EnumFilter<?, Enum<?>> aFilter, JCheckBox mainCB, GList<Enum<?>> mainList)
|
||||
{
|
||||
mainCB.setSelected(aFilter.getIsEnabled());
|
||||
mainList.setSelectedItems(aFilter.getSelectedItems());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Utility method to synchronize the specified filter with the associated GUI controls.
|
||||
*/
|
||||
public static void getRangeFilter(RangeFilter<?> aFilter, JCheckBox mainCB, JCheckBox minCB, JCheckBox maxCB, GNumberField minNF, GNumberField maxNF)
|
||||
public static void getRangeFilter(RangeFilter<?> aFilter, JCheckBox mainCB, JCheckBox minCB, JCheckBox maxCB,
|
||||
GNumberField minNF, GNumberField maxNF)
|
||||
{
|
||||
aFilter.setIsEnabled(mainCB.isSelected());
|
||||
aFilter.setUseMin(minCB.isSelected());
|
||||
@@ -59,9 +75,10 @@ public class FilterUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to synchronize the associated GUI controls with the specified filter.
|
||||
* Utility method to synchronize the associated GUI controls with the specified filter.
|
||||
*/
|
||||
public static void setRangeGui(RangeFilter<?> aFilter, JCheckBox mainCB, JCheckBox minCB, JCheckBox maxCB, GNumberField minNF, GNumberField maxNF)
|
||||
public static void setRangeGui(RangeFilter<?> aFilter, JCheckBox mainCB, JCheckBox minCB, JCheckBox maxCB,
|
||||
GNumberField minNF, GNumberField maxNF)
|
||||
{
|
||||
mainCB.setSelected(aFilter.getIsEnabled());
|
||||
minCB.setSelected(aFilter.getUseMin());
|
||||
@@ -71,26 +88,23 @@ public class FilterUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to keep the various GUI components associated with an EnumFilter synchronized.
|
||||
* The mainList will be enabled/disabled based on the selection state of mainCB.
|
||||
* Utility method to keep the various GUI components associated with an EnumFilter synchronized. The mainList will be
|
||||
* enabled/disabled based on the selection state of mainCB.
|
||||
*/
|
||||
public static void syncEnumGui(JCheckBox mainCB, GList<Enum<?>> mainList)
|
||||
{
|
||||
boolean isEnabled;
|
||||
|
||||
isEnabled = mainCB.isSelected();
|
||||
var isEnabled = mainCB.isSelected();
|
||||
mainList.setEnabled(isEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to keep the various GUI components associated with an RangeFilter synchronized.
|
||||
* Gui components will be enabled/disabled based on the various check boxes.
|
||||
* Utility method to keep the various GUI components associated with an RangeFilter synchronized. Gui components will
|
||||
* be enabled/disabled based on the various check boxes.
|
||||
*/
|
||||
public static void syncRangeGui(JCheckBox mainCB, JCheckBox minCB, JCheckBox maxCB, GNumberField minNF, GNumberField maxNF)
|
||||
public static void syncRangeGui(JCheckBox mainCB, JCheckBox minCB, JCheckBox maxCB, GNumberField minNF,
|
||||
GNumberField maxNF)
|
||||
{
|
||||
boolean isEnabled;
|
||||
|
||||
isEnabled = mainCB.isSelected();
|
||||
var isEnabled = mainCB.isSelected();
|
||||
minCB.setEnabled(isEnabled);
|
||||
maxCB.setEnabled(isEnabled);
|
||||
minNF.setEnabled(isEnabled & minCB.isSelected());
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.filter;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import glum.zio.ZinStream;
|
||||
import glum.zio.ZoutStream;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* A Filter which does not filter anything. Thus the method isValid() always returns true.
|
||||
* A {@link Filter} which does not filter anything. Thus the method isValid() always returns true.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*
|
||||
* @param <G1>
|
||||
*/
|
||||
public class NullFilter<G1> implements Filter<G1>
|
||||
{
|
||||
|
||||
@@ -1,25 +1,39 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.filter;
|
||||
|
||||
import glum.zio.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import glum.zio.*;
|
||||
|
||||
/**
|
||||
* Abstract filter which is used to filter a single value between the specified min/max ranges. The only code to write
|
||||
* is the isValid() method and to call the appropriate Constructor. In the isValid() method, you should delegate filter
|
||||
* logic to the method testIsValid() with the quantity of interest, and return the result from the method call.
|
||||
* Abstract {@link Filter} which is used to filter a single value between the specified min/max ranges. The only code to
|
||||
* write is the isValid() method. In the isValid() method, you should delegate filter logic to the method testIsValid()
|
||||
* with the quantity of interest, and return the result from the method call.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*
|
||||
* @param <G1>
|
||||
*/
|
||||
public abstract class RangeFilter<G1> implements ZioObj, Filter<G1>
|
||||
public abstract class RangeFilter<G1> implements Filter<G1>, ZioObj
|
||||
{
|
||||
// State vars
|
||||
private boolean isEnabled;
|
||||
private boolean useMin, useMax;
|
||||
private double minValue, maxValue;
|
||||
|
||||
/**
|
||||
* @param aBinCode
|
||||
* Unique identifier used during serialization. The value specified here should not collide with any other
|
||||
* codes for which there is serialization.
|
||||
*/
|
||||
/** Standard Constructor */
|
||||
public RangeFilter()
|
||||
{
|
||||
isEnabled = false;
|
||||
@@ -38,7 +52,7 @@ public abstract class RangeFilter<G1> implements ZioObj, Filter<G1>
|
||||
public boolean getUseMax() { return useMax; }
|
||||
public double getMinValue() { return minValue; }
|
||||
public double getMaxValue() { return maxValue; }
|
||||
|
||||
|
||||
public void setIsEnabled(boolean aBool) { isEnabled = aBool; }
|
||||
public void setUseMin(boolean aBool) { useMin = aBool; }
|
||||
public void setUseMax(boolean aBool) { useMax = aBool; }
|
||||
@@ -61,11 +75,9 @@ public abstract class RangeFilter<G1> implements ZioObj, Filter<G1>
|
||||
@Override
|
||||
public void zioRead(ZinStream aStream) throws IOException
|
||||
{
|
||||
byte bSwitch;
|
||||
|
||||
aStream.readVersion(0);
|
||||
|
||||
bSwitch = aStream.readByte();
|
||||
byte bSwitch = aStream.readByte();
|
||||
isEnabled = (bSwitch & 0x1) != 0;
|
||||
useMin = (bSwitch & 0x2) != 0;
|
||||
useMax = (bSwitch & 0x4) != 0;
|
||||
@@ -80,11 +92,9 @@ public abstract class RangeFilter<G1> implements ZioObj, Filter<G1>
|
||||
@Override
|
||||
public void zioWrite(ZoutStream aStream) throws IOException
|
||||
{
|
||||
byte bSwitch;
|
||||
|
||||
aStream.writeVersion(0);
|
||||
|
||||
bSwitch = 0;
|
||||
byte bSwitch = 0;
|
||||
if (isEnabled == true)
|
||||
bSwitch |= 0x1;
|
||||
if (useMin == true)
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
48
src/glum/gui/GuiExeUtil.java
Normal file
48
src/glum/gui/GuiExeUtil.java
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.HierarchyEvent;
|
||||
import java.awt.event.HierarchyListener;
|
||||
|
||||
/**
|
||||
* Collection of execution utilities used to execute behavior at a specific time frame associated with the life cycle of
|
||||
* AWT/Swing components.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GuiExeUtil
|
||||
{
|
||||
/**
|
||||
* Utility method to execute the Runnable once the specified Component is "showing" on the screen.
|
||||
*/
|
||||
public static void executeOnceWhenShowing(Component aComp, Runnable aRunnable)
|
||||
{
|
||||
aComp.addHierarchyListener(new HierarchyListener() {
|
||||
|
||||
@Override
|
||||
public void hierarchyChanged(HierarchyEvent aEvent)
|
||||
{
|
||||
if (aComp.isShowing() == false)
|
||||
return;
|
||||
|
||||
aRunnable.run();
|
||||
aComp.removeHierarchyListener(this);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
91
src/glum/gui/GuiPaneUtil.java
Normal file
91
src/glum/gui/GuiPaneUtil.java
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui;
|
||||
|
||||
import java.awt.Component;
|
||||
|
||||
import javax.swing.RootPaneContainer;
|
||||
|
||||
import glum.gui.panel.generic.MessagePanel;
|
||||
import glum.util.ThreadUtil;
|
||||
|
||||
/**
|
||||
* Collection of AWT/Swing utilities for showing various message panes.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GuiPaneUtil
|
||||
{
|
||||
/**
|
||||
* Utility method to display an alert messages.
|
||||
* <p>
|
||||
* Alert panel will have a nominal size of 750, 300.
|
||||
*/
|
||||
public static void showAlertMessage(Component aParent, String aTitle, String aInfoMsg)
|
||||
{
|
||||
// Delegate
|
||||
showFailMessage(aParent, aTitle, aInfoMsg, null, 750, 300);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to display failure messages.
|
||||
* <p>
|
||||
* If a stack trace is specified (not null) then the {@link Throwable} will be displayed below aInfoMsg.
|
||||
*/
|
||||
public static void showFailMessage(Component aParent, String aTitle, String aInfoMsg, Throwable aExp, int aMaxW,
|
||||
int aMaxH)
|
||||
{
|
||||
// Compute the panel size
|
||||
int compW = aMaxW;
|
||||
int compH = aMaxH;
|
||||
RootPaneContainer tmpRPC = GuiUtil.getRootPaneContainer(aParent);
|
||||
if (tmpRPC instanceof Component)
|
||||
{
|
||||
Component tmpComp = (Component) tmpRPC;
|
||||
compW = (int) (tmpComp.getWidth() * 0.80);
|
||||
compH = (int) (tmpComp.getHeight() * 0.80);
|
||||
}
|
||||
if (compW > aMaxW)
|
||||
compW = aMaxW;
|
||||
if (compH > aMaxH)
|
||||
compH = aMaxH;
|
||||
|
||||
// Setup the info message
|
||||
String infoMsg = "";
|
||||
if (aInfoMsg != null)
|
||||
infoMsg = aInfoMsg;
|
||||
|
||||
if (aExp != null)
|
||||
infoMsg += "\n" + ThreadUtil.getStackTraceClassic(aExp);
|
||||
|
||||
MessagePanel tmpPanel = new MessagePanel(aParent, aTitle, compW, compH);
|
||||
tmpPanel.setInfo(infoMsg, 0);
|
||||
tmpPanel.setTabSize(2);
|
||||
tmpPanel.setVisibleAsModal();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to display failure messages.
|
||||
* <p>
|
||||
* The stack trace of the {@link Throwable} will be displayed below aInfoMsg.
|
||||
* <p>
|
||||
* Error panel will have a nominal size of 750, 300.
|
||||
*/
|
||||
public static void showFailMessage(Component aParent, String aTitle, String aInfoMsg, Throwable aExp)
|
||||
{
|
||||
// Delegate
|
||||
showFailMessage(aParent, aTitle, aInfoMsg, aExp, 750, 300);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,22 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -11,28 +26,29 @@ import javax.swing.event.ChangeListener;
|
||||
import glum.gui.icon.IconUtil;
|
||||
import glum.reflect.Function;
|
||||
|
||||
/**
|
||||
* Collection of AWT/Swing utilities.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GuiUtil
|
||||
{
|
||||
/**
|
||||
* Method to examine the labels and returns the size of the largest button.
|
||||
*/
|
||||
public static Dimension computePreferredJButtonSize(String... labels)
|
||||
public static Dimension computePreferredJButtonSize(String... aLabelArr)
|
||||
{
|
||||
Dimension tmpDim, maxDim;
|
||||
JButton tmpB;
|
||||
|
||||
maxDim = null;
|
||||
tmpB = new JButton("");
|
||||
Dimension maxDim = null;
|
||||
var tmpB = new JButton("");
|
||||
|
||||
// Find the label that requires the largest dimension
|
||||
for (String aStr : labels)
|
||||
for (String aStr : aLabelArr)
|
||||
{
|
||||
if (aStr == null)
|
||||
aStr = "";
|
||||
|
||||
tmpB.setText(aStr);
|
||||
tmpDim = tmpB.getPreferredSize();
|
||||
|
||||
var tmpDim = tmpB.getPreferredSize();
|
||||
if (maxDim == null || maxDim.getWidth() < tmpDim.getWidth())
|
||||
maxDim = tmpDim;
|
||||
}
|
||||
@@ -45,30 +61,29 @@ public class GuiUtil
|
||||
*/
|
||||
public static JButton createJButton(String aTitle, ActionListener aActionListener)
|
||||
{
|
||||
JButton tmpB;
|
||||
|
||||
tmpB = new JButton(aTitle);
|
||||
var tmpB = new JButton(aTitle);
|
||||
tmpB.addActionListener(aActionListener);
|
||||
|
||||
return tmpB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the JRadioButton with the following attributes.
|
||||
* <p>
|
||||
* TODO: Do not remove this method until DistMaker has been updated...
|
||||
*/
|
||||
public static JButton createJButton(String aTitle, ActionListener aActionListener, Font aFont)
|
||||
{
|
||||
JButton tmpB;
|
||||
|
||||
tmpB = new JButton(aTitle);
|
||||
var tmpB = new JButton(aTitle);
|
||||
tmpB.addActionListener(aActionListener);
|
||||
if (aFont != null)
|
||||
tmpB.setFont(aFont);
|
||||
tmpB.setFont(aFont);
|
||||
|
||||
return tmpB;
|
||||
}
|
||||
|
||||
public static JButton createJButton(String aTitle, ActionListener aActionListener, Dimension aDimension)
|
||||
{
|
||||
JButton tmpB;
|
||||
|
||||
tmpB = new JButton(aTitle);
|
||||
var tmpB = new JButton(aTitle);
|
||||
tmpB.addActionListener(aActionListener);
|
||||
|
||||
// Force a dimension
|
||||
@@ -89,9 +104,7 @@ public class GuiUtil
|
||||
|
||||
public static JButton createJButton(Icon aIcon, ActionListener aActionListener, String aToolTip)
|
||||
{
|
||||
JButton tmpB;
|
||||
|
||||
tmpB = new JButton(aIcon);
|
||||
var tmpB = new JButton(aIcon);
|
||||
tmpB.addActionListener(aActionListener);
|
||||
|
||||
if (aToolTip != null)
|
||||
@@ -110,9 +123,7 @@ public class GuiUtil
|
||||
|
||||
public static JButton createJButtonViaResource(ActionListener aHandler, String aResourcePath, String aToolTip)
|
||||
{
|
||||
JButton tmpB;
|
||||
|
||||
tmpB = new JButton(IconUtil.loadIcon(aResourcePath));
|
||||
var tmpB = new JButton(IconUtil.loadIcon(aResourcePath));
|
||||
tmpB.addActionListener(aHandler);
|
||||
|
||||
if (aToolTip != null)
|
||||
@@ -126,47 +137,12 @@ public class GuiUtil
|
||||
*/
|
||||
public static JCheckBox createJCheckBox(String aTitle, ActionListener aActionListener)
|
||||
{
|
||||
return createJCheckBox(aTitle, aActionListener, null);
|
||||
}
|
||||
|
||||
public static JCheckBox createJCheckBox(String aTitle, ActionListener aActionListener, Font aFont)
|
||||
{
|
||||
JCheckBox tmpCB;
|
||||
|
||||
tmpCB = new JCheckBox(aTitle);
|
||||
var tmpCB = new JCheckBox(aTitle);
|
||||
tmpCB.addActionListener(aActionListener);
|
||||
if (aFont != null)
|
||||
tmpCB.setFont(aFont);
|
||||
|
||||
return tmpCB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JComboBox with the specified settings
|
||||
*/
|
||||
public static <G1> JComboBox<G1> createJComboBox(ActionListener aListener, Font aFont, Collection<G1> aItemL)
|
||||
{
|
||||
JComboBox<G1> tmpBox;
|
||||
|
||||
tmpBox = new JComboBox<G1>();
|
||||
for (G1 aItem : aItemL)
|
||||
tmpBox.addItem(aItem);
|
||||
|
||||
if (aFont != null)
|
||||
tmpBox.setFont(aFont);
|
||||
|
||||
tmpBox.addActionListener(aListener);
|
||||
return tmpBox;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Creates a JComboBox with the specified settings
|
||||
// */
|
||||
// public static JComboBox createJComboBox(ActionListener aListener, Object... itemArr)
|
||||
// {
|
||||
// return createJComboBox(aListener, null, itemArr);
|
||||
// }
|
||||
|
||||
/**
|
||||
* Creates a JLabel with the specified settings
|
||||
*/
|
||||
@@ -177,10 +153,7 @@ public class GuiUtil
|
||||
|
||||
public static JLabel createJLabel(String aTitle, int aAlignment, Font aFont)
|
||||
{
|
||||
JLabel tmpL;
|
||||
|
||||
tmpL = new JLabel(aTitle, aAlignment);
|
||||
|
||||
var tmpL = new JLabel(aTitle, aAlignment);
|
||||
if (aFont != null)
|
||||
tmpL.setFont(aFont);
|
||||
|
||||
@@ -188,48 +161,63 @@ public class GuiUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the JRadioButton with the following attributes.
|
||||
* Creates the {@link JComboBox} with the following attributes.
|
||||
*/
|
||||
public static JRadioButton createJRadioButton(String aLabel, ActionListener aListener)
|
||||
public static <G1> JComboBox<G1> createComboBox(ActionListener aListener, Collection<G1> aItemC)
|
||||
{
|
||||
return createJRadioButton(aLabel, aListener, null);
|
||||
var retBox = new JComboBox<G1>();
|
||||
for (G1 aItem : aItemC)
|
||||
retBox.addItem(aItem);
|
||||
|
||||
retBox.addActionListener(aListener);
|
||||
|
||||
return retBox;
|
||||
}
|
||||
|
||||
public static JRadioButton createJRadioButton(String aLabel, ActionListener aListener, Font aFont)
|
||||
/**
|
||||
* Creates the JRadioButton with the following attributes.
|
||||
*/
|
||||
public static JRadioButton createJRadioButton(ItemListener aListener, String aLabel)
|
||||
{
|
||||
JRadioButton tmpRB;
|
||||
var retRB = new JRadioButton(aLabel);
|
||||
retRB.addItemListener(aListener);
|
||||
|
||||
tmpRB = new JRadioButton(aLabel);
|
||||
tmpRB.addActionListener(aListener);
|
||||
if (aFont != null)
|
||||
tmpRB.setFont(aFont);
|
||||
return retRB;
|
||||
}
|
||||
|
||||
return tmpRB;
|
||||
/**
|
||||
* Creates the JRadioButton with the following attributes.
|
||||
* <p>
|
||||
* TODO: Do not remove this method until DistMaker has been updated...
|
||||
*/
|
||||
public static JRadioButton createJRadioButton(ItemListener aListener, String aLabel, Font aFont)
|
||||
{
|
||||
var retRB = new JRadioButton(aLabel);
|
||||
retRB.addItemListener(aListener);
|
||||
retRB.setFont(aFont);
|
||||
|
||||
return retRB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method for creating a visual thin divider
|
||||
* <P>
|
||||
* <p>
|
||||
* Typically added to MigLayout (or like manager) with: add(aComp, "growx,h 4!,span,wrap");
|
||||
*/
|
||||
public static JPanel createDivider()
|
||||
{
|
||||
JPanel tmpPanel;
|
||||
var retPanel = new JPanel();
|
||||
retPanel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
|
||||
tmpPanel = new JPanel();
|
||||
tmpPanel.setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
|
||||
return tmpPanel;
|
||||
return retPanel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an uneditable JTextArea with no border, non-opaque, line wrap enabled and word wrap enabled.
|
||||
* Creates an uneditable JTextArea with the settings: non-opaque, line wrap enabled and word wrap enabled.
|
||||
*/
|
||||
public static JTextArea createUneditableTextArea(int rows, int cols)
|
||||
{
|
||||
JTextArea tmpTA;
|
||||
|
||||
tmpTA = new JTextArea("", rows, cols);
|
||||
var tmpTA = new JTextArea("", rows, cols);
|
||||
tmpTA.setEditable(false);
|
||||
tmpTA.setOpaque(false);
|
||||
tmpTA.setLineWrap(true);
|
||||
@@ -243,9 +231,7 @@ public class GuiUtil
|
||||
*/
|
||||
public static JTextPane createUneditableTextPane()
|
||||
{
|
||||
JTextPane tmpTP;
|
||||
|
||||
tmpTP = new JTextPane();
|
||||
var tmpTP = new JTextPane();
|
||||
tmpTP.setEditable(false);
|
||||
tmpTP.setOpaque(false);
|
||||
tmpTP.setContentType("text/html");
|
||||
@@ -258,9 +244,7 @@ public class GuiUtil
|
||||
*/
|
||||
public static JTextField createUneditableTextField(String aTitle)
|
||||
{
|
||||
JTextField tmpTF;
|
||||
|
||||
tmpTF = new JTextField(aTitle);
|
||||
var tmpTF = new JTextField(aTitle);
|
||||
tmpTF.setBorder(null);
|
||||
tmpTF.setEditable(false);
|
||||
tmpTF.setOpaque(false);
|
||||
@@ -268,134 +252,103 @@ public class GuiUtil
|
||||
return tmpTF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility helper method to create a JButton with the specified configuration.
|
||||
*
|
||||
* @param aListener
|
||||
* A Listener registered with the JButton.
|
||||
* @param aIcon
|
||||
* The icon associated with the button
|
||||
*/
|
||||
public static JButton formButton(ActionListener aListener, Icon aIcon)
|
||||
{
|
||||
var retB = new JButton();
|
||||
retB.addActionListener(aListener);
|
||||
retB.setIcon(aIcon);
|
||||
return retB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility helper method to create a JButton with the specified configuration.
|
||||
*
|
||||
* @param aListener
|
||||
* A Listener registered with the JButton.
|
||||
* @param aImage
|
||||
* The image to be used as an icon.
|
||||
* @param aToolTip
|
||||
* The tool tip associated with the JButton.
|
||||
*/
|
||||
public static JButton formButton(ActionListener aListener, BufferedImage aImage, String aToolTip)
|
||||
{
|
||||
var tmpIcon = new ImageIcon(aImage);
|
||||
|
||||
var retB = new JButton();
|
||||
retB.setIcon(tmpIcon);
|
||||
retB.addActionListener(aListener);
|
||||
retB.setToolTipText(aToolTip);
|
||||
|
||||
return retB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility helper method to create a JButton with the specified configuration.
|
||||
*
|
||||
* @param aListener
|
||||
* A Listener registered with the JButton.
|
||||
* @param aTitle
|
||||
* The text title of the JButton.
|
||||
*/
|
||||
public static JButton formButton(ActionListener aListener, String aTitle)
|
||||
{
|
||||
var retB = new JButton();
|
||||
retB.addActionListener(aListener);
|
||||
retB.setText(aTitle);
|
||||
return retB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility helper method to create a JToggleButton with the specified configuration.
|
||||
*
|
||||
* @param aListener
|
||||
* A Listener registered with the JButton.
|
||||
* @param aPriIcon
|
||||
* The icon to be used as the primary (unselected) icon.
|
||||
* @param aSecIcon
|
||||
* The icon to be used when the secondary (selected) icon.
|
||||
* @param aToolTip
|
||||
* The tool tip associated with the JToggleButton.
|
||||
*/
|
||||
public static JToggleButton formToggleButton(ActionListener aListener, Icon aPriIcon, Icon aSecIcon)
|
||||
{
|
||||
var retTB = new JToggleButton(aPriIcon, false);
|
||||
retTB.setSelectedIcon(aSecIcon);
|
||||
retTB.addActionListener(aListener);
|
||||
|
||||
return retTB;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to link a set of radio buttons together
|
||||
*/
|
||||
public static void linkRadioButtons(JRadioButton... buttonArr)
|
||||
public static ButtonGroup linkRadioButtons(JRadioButton... aButtonArr)
|
||||
{
|
||||
ButtonGroup tmpGroup;
|
||||
var retGroup = new ButtonGroup();
|
||||
for (var aItem : aButtonArr)
|
||||
retGroup.add(aItem);
|
||||
|
||||
tmpGroup = new ButtonGroup();
|
||||
for (JRadioButton aItem : buttonArr)
|
||||
tmpGroup.add(aItem);
|
||||
return retGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a boolean from a string with out throwing a exception
|
||||
* Utility method to link a set of radio buttons together
|
||||
*/
|
||||
public static boolean readBoolean(String aStr, boolean aVal)
|
||||
public static ButtonGroup linkRadioButtons(Collection<JRadioButton> aButtonC)
|
||||
{
|
||||
if (aStr == null)
|
||||
return aVal;
|
||||
var retGroup = new ButtonGroup();
|
||||
for (var aItem : aButtonC)
|
||||
retGroup.add(aItem);
|
||||
|
||||
// Special case for 1 char strings
|
||||
if (aStr.length() == 1)
|
||||
{
|
||||
char aChar;
|
||||
|
||||
aChar = aStr.charAt(0);
|
||||
if (aChar == 'T' || aChar == 't' || aChar == '1')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Boolean.valueOf(aStr).booleanValue();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return aVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a double from a string with out throwing a exception. Note aStr can have an number of separators: comma
|
||||
* chars
|
||||
*/
|
||||
public static double readDouble(String aStr, double aVal)
|
||||
{
|
||||
try
|
||||
{
|
||||
aStr = aStr.replace(",", "");
|
||||
return Double.parseDouble(aStr);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return aVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a float from a string with out throwing a exception. Note aStr can have an number of separators: comma chars
|
||||
*/
|
||||
public static float readFloat(String aStr, float aVal)
|
||||
{
|
||||
try
|
||||
{
|
||||
aStr = aStr.replace(",", "");
|
||||
return Float.parseFloat(aStr);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return aVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an int from a string without throwing a exception Note aStr can have an number of separators: comma chars
|
||||
*/
|
||||
public static int readInt(String aStr, int aVal)
|
||||
{
|
||||
try
|
||||
{
|
||||
aStr = aStr.replace(",", "");
|
||||
return Integer.parseInt(aStr);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return aVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a long from a string without throwing a exception Note aStr can have an number of separators: comma chars
|
||||
*/
|
||||
public static long readLong(String aStr, long aVal)
|
||||
{
|
||||
try
|
||||
{
|
||||
aStr = aStr.replace(",", "");
|
||||
return Long.parseLong(aStr);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return aVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an int (forced to fit within a range) from a string with out throwing a exception
|
||||
*/
|
||||
public static int readRangeInt(String aStr, int minVal, int maxVal, int aVal)
|
||||
{
|
||||
int aInt;
|
||||
|
||||
try
|
||||
{
|
||||
aInt = Integer.parseInt(aStr);
|
||||
if (aInt < minVal)
|
||||
aInt = minVal;
|
||||
else if (aInt > maxVal)
|
||||
aInt = maxVal;
|
||||
|
||||
return aInt;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return aVal;
|
||||
}
|
||||
return retGroup;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -403,28 +356,27 @@ public class GuiUtil
|
||||
*/
|
||||
public static RootPaneContainer getRootPaneContainer(Component aComponent)
|
||||
{
|
||||
Container aParent;
|
||||
|
||||
// Check to see if the Component is an actual RootPaneContainer
|
||||
if (aComponent instanceof RootPaneContainer)
|
||||
return (RootPaneContainer)aComponent;
|
||||
return (RootPaneContainer) aComponent;
|
||||
|
||||
// Attempt to locate the RootPaneContainer (through our stack)
|
||||
aParent = aComponent.getParent();
|
||||
while (aParent != null && (aParent instanceof RootPaneContainer) == false)
|
||||
aParent = aParent.getParent();
|
||||
var retParent = aComponent.getParent();
|
||||
while (retParent != null && (retParent instanceof RootPaneContainer) == false)
|
||||
retParent = retParent.getParent();
|
||||
|
||||
// Bail if we failed to find the RootPaneContainer
|
||||
if (aParent instanceof RootPaneContainer == false)
|
||||
if (retParent instanceof RootPaneContainer == false)
|
||||
throw new RuntimeException("No valid (grand)parent associated with GlassPane.");
|
||||
|
||||
return (RootPaneContainer)aParent;
|
||||
return (RootPaneContainer) retParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to locate all of the subcomponents contained in aContainer which are an instance of searchClass
|
||||
*/
|
||||
public static void locateAllSubComponents(Container aContainer, Collection<Component> itemList, Class<?>... searchClassArr)
|
||||
public static void locateAllSubComponents(Container aContainer, Collection<Component> itemList,
|
||||
Class<?>... searchClassArr)
|
||||
{
|
||||
for (Component aComponent : aContainer.getComponents())
|
||||
{
|
||||
@@ -438,13 +390,14 @@ public class GuiUtil
|
||||
}
|
||||
|
||||
if (aComponent instanceof Container)
|
||||
locateAllSubComponents((Container)aComponent, itemList, searchClassArr);
|
||||
locateAllSubComponents((Container) aComponent, itemList, searchClassArr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to force a Component to act as modal while it is visible Source:
|
||||
* http://stackoverflow.com/questions/804023/how-do-i-simulate-a-modal-dialog-from-within-an-applet
|
||||
* Utility method to force a Component to act as modal while it is visible
|
||||
* <p>
|
||||
* Source: http://stackoverflow.com/questions/804023/how-do-i-simulate-a-modal-dialog-from-within-an-applet
|
||||
*/
|
||||
public static void modalWhileVisible(Component aComponent)
|
||||
{
|
||||
@@ -452,27 +405,27 @@ public class GuiUtil
|
||||
if (SwingUtilities.isEventDispatchThread() == false)
|
||||
throw new RuntimeException("Visibility for modal components must be changed via the Event thread.");
|
||||
|
||||
synchronized(aComponent)
|
||||
synchronized (aComponent)
|
||||
{
|
||||
try
|
||||
{
|
||||
EventQueue theQueue = aComponent.getToolkit().getSystemEventQueue();
|
||||
var theQueue = aComponent.getToolkit().getSystemEventQueue();
|
||||
while (aComponent.isVisible())
|
||||
{
|
||||
//System.out.println("About to dispatch event... component.isVisible():" + aComponent.isVisible());
|
||||
AWTEvent event = theQueue.getNextEvent();
|
||||
Object source = event.getSource();
|
||||
var event = theQueue.getNextEvent();
|
||||
var source = event.getSource();
|
||||
if (event instanceof ActiveEvent)
|
||||
{
|
||||
((ActiveEvent)event).dispatch();
|
||||
((ActiveEvent) event).dispatch();
|
||||
}
|
||||
else if (source instanceof Component)
|
||||
{
|
||||
((Component)source).dispatchEvent(event);
|
||||
((Component) source).dispatchEvent(event);
|
||||
}
|
||||
else if (source instanceof MenuComponent)
|
||||
{
|
||||
((MenuComponent)source).dispatchEvent(event);
|
||||
((MenuComponent) source).dispatchEvent(event);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -480,7 +433,7 @@ public class GuiUtil
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(InterruptedException ignored)
|
||||
catch (InterruptedException ignored)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -489,18 +442,16 @@ public class GuiUtil
|
||||
/**
|
||||
* Utility to call a specific method (methodName) with specific parameters (aParamArr) on aComp and on all of the
|
||||
* child subcomponents. The method will only be called if the components are an instance of refMatchClass.
|
||||
* <P>
|
||||
* This is useful so that a component and all of its children can be disabled, hidden, etc<BR>
|
||||
* <p>
|
||||
* This is useful so that a component and all of its children can be disabled, hidden, etc</br>
|
||||
* Example: GuiUtil.callMethod(myPanel, setEnabled, false);
|
||||
* <P>
|
||||
* <p>
|
||||
* Be aware, this is rather expensive, so do not call in time critical applications.
|
||||
*/
|
||||
public static void callMethod(Component aComp, Class<?> refMatchClass, String aMethodName, Object... aParamArr)
|
||||
{
|
||||
Class<?>[] typeArr;
|
||||
|
||||
// Construct the associated type array
|
||||
typeArr = new Class[0];
|
||||
var typeArr = new Class<?>[0];
|
||||
if (aParamArr.length > 0)
|
||||
{
|
||||
// Determine the types of the specified arguments
|
||||
@@ -520,24 +471,22 @@ public class GuiUtil
|
||||
/**
|
||||
* Helper method to callMethod
|
||||
*/
|
||||
private static void callMethodHelper(Component aComp, Class<?> refMatchClass, String aMethodName, Class<?>[] aTypeArr, Object[] aParamArr)
|
||||
private static void callMethodHelper(Component aComp, Class<?> refMatchClass, String aMethodName,
|
||||
Class<?>[] aTypeArr, Object[] aParamArr)
|
||||
{
|
||||
Component[] subCompArr;
|
||||
Function aFunction;
|
||||
|
||||
// Locate and call the actual method
|
||||
if (refMatchClass.isInstance(aComp) == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
aFunction = new Function(aComp, aMethodName, aTypeArr);
|
||||
aFunction.invoke(aParamArr);
|
||||
var tmpFunction = new Function(aComp, aMethodName, aTypeArr);
|
||||
tmpFunction.invoke(aParamArr);
|
||||
}
|
||||
catch(NoSuchMethodException aExp1)
|
||||
catch (NoSuchMethodException aExp1)
|
||||
{
|
||||
throw new RuntimeException("Failed to locate valid function. Method:" + aMethodName, aExp1);
|
||||
}
|
||||
catch(Exception aExp2)
|
||||
catch (Exception aExp2)
|
||||
{
|
||||
throw new RuntimeException("Failed to execute function. Method:" + aMethodName, aExp2);
|
||||
}
|
||||
@@ -548,34 +497,44 @@ public class GuiUtil
|
||||
return;
|
||||
|
||||
// Recurse down our children
|
||||
subCompArr = ((Container)aComp).getComponents();
|
||||
var subCompArr = ((Container) aComp).getComponents();
|
||||
for (Component aSubComp : subCompArr)
|
||||
callMethodHelper(aSubComp, refMatchClass, aMethodName, aTypeArr, aParamArr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to set all subcomponents to the specified enabled mode.
|
||||
* Utility method to recursively change the enable state of all Components contained by the specified Container.
|
||||
*
|
||||
* @param aContainer
|
||||
* The Container of interest.
|
||||
* @param aBool
|
||||
* Boolean used to define the enable state.
|
||||
*/
|
||||
// TODO: Phase this method out, replace with callMethod()
|
||||
public static void setEnabled(Component aComp, boolean aBool)
|
||||
public static void setEnabled(Container aContainer, boolean aBool)
|
||||
{
|
||||
Component[] subCompArr;
|
||||
|
||||
aComp.setEnabled(aBool);
|
||||
if (aComp instanceof Container == false)
|
||||
return;
|
||||
|
||||
subCompArr = ((Container)aComp).getComponents();
|
||||
for (Component aSubComp : subCompArr)
|
||||
GuiUtil.setEnabled(aSubComp, aBool);
|
||||
for (Component aComp : aContainer.getComponents())
|
||||
{
|
||||
aComp.setEnabled(aBool);
|
||||
if (aComp instanceof Container)
|
||||
setEnabled((Container) aComp, aBool);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to set the enabled switch on all of the specified components.
|
||||
* Utility method to set the enable state on all of the specified components.
|
||||
*/
|
||||
public static void setEnabled(boolean aBool, Component... componentArr)
|
||||
public static void setEnabled(boolean aBool, Component... aComponentArr)
|
||||
{
|
||||
for (Component aComp : componentArr)
|
||||
for (Component aComp : aComponentArr)
|
||||
aComp.setEnabled(aBool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to set the enable state on all of the specified components.
|
||||
*/
|
||||
public static void setEnabled(boolean aBool, Collection<? extends Component> aComponentC)
|
||||
{
|
||||
for (Component aComp : aComponentC)
|
||||
aComp.setEnabled(aBool);
|
||||
}
|
||||
|
||||
@@ -592,43 +551,48 @@ public class GuiUtil
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that takes up to 8 buttons and converts all of their selection states to a single byte.
|
||||
* Utility method that returns a bitmask composed of the selection state of the specified buttons.
|
||||
* <p>
|
||||
* The array is transformed such that the least significant bit is assumed to have index position 0 with the higher
|
||||
* bits corresponding to a larger (array) index.
|
||||
* <p>
|
||||
* A maximum of 32 buttons is support. Passing in more than 32 buttons will result in an exception.
|
||||
*/
|
||||
public static byte getSelectionStateAsByte(AbstractButton... buttonArr)
|
||||
public static int getSelectionStateAsBitMask(AbstractButton... aButtonArr)
|
||||
{
|
||||
byte retByte;
|
||||
if (aButtonArr.length > 32)
|
||||
throw new RuntimeException("Improper API call. Max of 32 buttons supported. Passed: " + aButtonArr.length);
|
||||
|
||||
if (buttonArr.length > 8)
|
||||
throw new RuntimeException("Improper API call. Max of 8 buttons supported. Passed: " + buttonArr.length);
|
||||
|
||||
retByte = 0;
|
||||
for (int c1 = 0; c1 < buttonArr.length; c1++)
|
||||
int retBitMask = 0;
|
||||
for (int c1 = 0; c1 < aButtonArr.length; c1++)
|
||||
{
|
||||
if (buttonArr[c1].isSelected() == true)
|
||||
retByte |= 1 << c1;
|
||||
if (aButtonArr[c1].isSelected() == true)
|
||||
retBitMask |= 1 << c1;
|
||||
}
|
||||
|
||||
return retByte;
|
||||
return retBitMask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that takes up to 8 buttons and configures the selection state of the buttons to match the bit
|
||||
* pattern of aByte.
|
||||
* Utility method that updates the selection state of the provided buttons to reflect the specified bitmask.
|
||||
* <p>
|
||||
* The array is transformed such that the least significant bit is assumed to have index position 0 with the higher
|
||||
* bits corresponding to a larger (array) index.
|
||||
* <p>
|
||||
* A maximum of 32 buttons is support. Passing in more than 32 buttons will result in an exception.
|
||||
*/
|
||||
public static void setSelectionState(byte aByte, AbstractButton... buttonArr)
|
||||
public static void setSelectionStateFromBitMask(int aBitMask, AbstractButton... aButtonArr)
|
||||
{
|
||||
boolean aBool;
|
||||
if (aButtonArr.length > 32)
|
||||
throw new RuntimeException("Improper API call. Max of 32 buttons supported. Passed: " + aButtonArr.length);
|
||||
|
||||
if (buttonArr.length > 8)
|
||||
throw new RuntimeException("Improper API call. Max of 8 buttons supported. Passed: " + buttonArr.length);
|
||||
|
||||
for (int c1 = 0; c1 < buttonArr.length; c1++)
|
||||
for (int c1 = 0; c1 < aButtonArr.length; c1++)
|
||||
{
|
||||
aBool = false;
|
||||
if (((0x01 << c1) & aByte) != 0)
|
||||
aBool = true;
|
||||
var tmpBool = false;
|
||||
if (((0x01 << c1) & aBitMask) != 0)
|
||||
tmpBool = true;
|
||||
|
||||
buttonArr[c1].setSelected(aBool);
|
||||
aButtonArr[c1].setSelected(tmpBool);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,9 +601,7 @@ public class GuiUtil
|
||||
*/
|
||||
public static void updateSlider(JSlider aSlider, int aVal)
|
||||
{
|
||||
ChangeListener[] tmpArr;
|
||||
|
||||
tmpArr = aSlider.getChangeListeners();
|
||||
var tmpArr = aSlider.getChangeListeners();
|
||||
|
||||
for (ChangeListener aListener : tmpArr)
|
||||
aSlider.removeChangeListener(aListener);
|
||||
@@ -654,13 +616,13 @@ public class GuiUtil
|
||||
* Utility method that checks to ensure the current thread is running on the ATW thread. If it is NOT then the
|
||||
* specified Runnable will be posted so that it is called on the AWT thread. If it is running on the AWT thread then
|
||||
* nothing will happen and this method will return false.
|
||||
* <P>
|
||||
* <p>
|
||||
* Typically this utility method is called at the start of a function to ensure it is on the AWT thread, and if not
|
||||
* then schedule the function onto the AWT thread. Thus it is strongly advisable that if this method returns true the
|
||||
* caller should immediately exit.
|
||||
* <P>
|
||||
* <p>
|
||||
* <B>Typical usage within a method:</B>
|
||||
*
|
||||
*
|
||||
* <PRE>
|
||||
* public void actionPerformed(aEvent)
|
||||
* {
|
||||
@@ -668,7 +630,7 @@ public class GuiUtil
|
||||
* Runnable tmpRunnable = ()-> actionPerformed(aEvent);
|
||||
* if (redispatchOnAwtIfNeeded(this, "actionPerformed", aEvent) = true)
|
||||
* return;
|
||||
*
|
||||
*
|
||||
* // Do normal work ...
|
||||
* }
|
||||
* </PRE>
|
||||
|
||||
88
src/glum/gui/GuiUtilEx.java
Normal file
88
src/glum/gui/GuiUtilEx.java
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* Collection of additional AWT/Swing based utility methods.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GuiUtilEx
|
||||
{
|
||||
/**
|
||||
* Utility method that returns the default dimension for the main window.
|
||||
* <p>
|
||||
* The returned {@link Dimension} will have a minimum size of [aMinX,aMinY] or [80%,80%] of the screen resolution
|
||||
* (which ever is smaller).
|
||||
*/
|
||||
public static Dimension getDimensionDefaultMain(int aMinX, int aMinY)
|
||||
{
|
||||
var screenDim = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int winW = Math.min(aMinX, (int) (screenDim.getWidth() * 0.80));
|
||||
int winH = Math.min(aMinY, (int) (screenDim.getHeight() * 0.80));
|
||||
return new Dimension(winW, winH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns the default dimension for the main window.
|
||||
* <p>
|
||||
* The returned {@link Dimension} will have a minimum size of [950, 750] or 80% of the screen resolution.
|
||||
*/
|
||||
public static Dimension getDimensionDefaultMain()
|
||||
{
|
||||
// Delegate
|
||||
return getDimensionDefaultMain(950, 750);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns a new Dimension where the size has been scaled by the specified scalars.
|
||||
*
|
||||
* @param aDimension
|
||||
* The original dimension
|
||||
* @param aScalerX
|
||||
* Percent to scale the dimensions width.
|
||||
* @param aScalerY
|
||||
* Percent to scale the dimensions height.
|
||||
*/
|
||||
public static Dimension getDimensionScaled(Dimension aDimension, double aScalerX, double aScalerY)
|
||||
{
|
||||
int winW = Math.min(950, (int) (aDimension.getWidth() * aScalerX));
|
||||
int winH = Math.min(750, (int) (aDimension.getHeight() * aScalerY));
|
||||
return new Dimension(winW, winH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that returns the (first) parent that matches the specified Class. If there is no such component
|
||||
* then null will be returned.
|
||||
*/
|
||||
public static Component getParent(Component aComp, Class<?> aClass)
|
||||
{
|
||||
// Search through all the (grand)parents
|
||||
var parent = aComp.getParent();
|
||||
while (parent != null)
|
||||
{
|
||||
// Bail once we have a matching class
|
||||
if (parent.getClass() == aClass)
|
||||
return parent;
|
||||
|
||||
// Next parent
|
||||
parent = parent.getParent();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
185
src/glum/gui/TableUtil.java
Normal file
185
src/glum/gui/TableUtil.java
Normal file
@@ -0,0 +1,185 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.JTable;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
import glum.gui.table.TableSorter;
|
||||
import glum.item.ItemManager;
|
||||
|
||||
/**
|
||||
* Collection of utilities associated with JTables.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class TableUtil
|
||||
{
|
||||
|
||||
/**
|
||||
* Utility method to invert the selection on the specified table. The selection will be inverted with the specified
|
||||
* ListSelectionListener being ignored.
|
||||
*
|
||||
* @param aTable
|
||||
* The table for which the selection should be inverted.
|
||||
* @param aIgnoreListener
|
||||
* An ListSelectionListener that will not receive any intermediate events. It is important that this listener
|
||||
* be registered with the table's selection model as it will be deregistered and then later registered. If
|
||||
* null then this argument will be ignored.
|
||||
*/
|
||||
public static void invertSelection(JTable aTable, ListSelectionListener aIgnoreListener)
|
||||
{
|
||||
Set<Integer> oldSet = new HashSet<>();
|
||||
for (int aId : aTable.getSelectedRows())
|
||||
oldSet.add(aId);
|
||||
|
||||
int numRows = aTable.getRowCount();
|
||||
int[] tmpArr = new int[numRows - oldSet.size()];
|
||||
|
||||
// Determine the rows that are to be selected
|
||||
int idx = 0;
|
||||
for (int aId = 0; aId < numRows; aId++)
|
||||
{
|
||||
// Skip to next if row was previously selected
|
||||
if (oldSet.contains(aId) == true)
|
||||
continue;
|
||||
|
||||
tmpArr[idx] = aId;
|
||||
idx++;
|
||||
}
|
||||
|
||||
// Delegate
|
||||
setSortedSelection(aTable, aIgnoreListener, tmpArr);
|
||||
|
||||
// Send out a single event of the change
|
||||
if (aIgnoreListener != null)
|
||||
aIgnoreListener.valueChanged(new ListSelectionEvent(aTable, 0, aTable.getRowCount() - 1, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to select the rows at the specified indexes. The selection will be updated with the specified
|
||||
* ListSelectionListener being ignored.
|
||||
*
|
||||
* @param aTable
|
||||
* The table for which the selection should be updated.
|
||||
* @param aIgnoreListener
|
||||
* A ListSelectionListener that will not receive any intermediate events. It is important that this listener
|
||||
* be registered with the table's selection model as it will be deregistered and then later registered. If
|
||||
* null then this argument will be ignored.
|
||||
* @param aRowL
|
||||
* A list of indexes corresponding to the rows that are to be selected. All other rows will be unselected.
|
||||
*/
|
||||
public static void setSelection(JTable aTable, ListSelectionListener aIgnoreListener, List<Integer> aRowL)
|
||||
{
|
||||
// Transform to a sorted array
|
||||
int[] rowArr = Ints.toArray(aRowL);
|
||||
Arrays.parallelSort(rowArr);
|
||||
|
||||
// Delegate
|
||||
setSortedSelection(aTable, aIgnoreListener, rowArr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that will synchronize the table selection to match the selected items in the ItemManager. If new
|
||||
* items were selected then the table will be scrolled (to the first newly selected row).
|
||||
*/
|
||||
public static <G1> void updateTableSelection(ListSelectionListener aIgnoreListener, ItemManager<G1> aManager,
|
||||
JTable aTable, TableSorter aSortTableModel)
|
||||
{
|
||||
// Form a reverse lookup map of item to (view) index
|
||||
List<G1> fullItemL = aManager.getAllItems();
|
||||
Map<G1, Integer> revLookM = new HashMap<>();
|
||||
for (int aIdx = 0; aIdx < fullItemL.size(); aIdx++)
|
||||
{
|
||||
int tmpIdx = aSortTableModel.viewIndex(aIdx);
|
||||
revLookM.put(fullItemL.get(aIdx), tmpIdx);
|
||||
}
|
||||
|
||||
int[] idxArr = aTable.getSelectedRows();
|
||||
List<Integer> oldL = Ints.asList(idxArr);
|
||||
Set<Integer> oldS = new LinkedHashSet<>(oldL);
|
||||
|
||||
List<Integer> newL = new ArrayList<>();
|
||||
for (G1 aItem : aManager.getSelectedItems())
|
||||
newL.add(revLookM.get(aItem));
|
||||
Set<Integer> newS = new LinkedHashSet<>(newL);
|
||||
|
||||
// Bail if nothing has changed
|
||||
if (newS.equals(oldS) == true)
|
||||
return;
|
||||
|
||||
// Update the table's selection
|
||||
setSelection(aTable, aIgnoreListener, newL);
|
||||
aTable.repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility helper method that selects the specified rows.
|
||||
* <p>
|
||||
* The rows must be in sorted order.
|
||||
*
|
||||
* @param aTable
|
||||
* The table for which the selection should be updated.
|
||||
* @param aIgnoreListener
|
||||
* An ListSelectionListener that will not receive any intermediate events. It is important that this listener
|
||||
* be registered with the table's selection model as it will be deregistered and then later registered. If
|
||||
* null then this argument will be ignored.
|
||||
* @param aSortedRowArr
|
||||
* An array of indexes corresponding to the rows that are to be selected. All other rows will be unselected.
|
||||
*/
|
||||
private static void setSortedSelection(JTable aTable, ListSelectionListener aIgnoreListener, int[] aSortedRowArr)
|
||||
{
|
||||
// Initial range
|
||||
int begIdx = -1;
|
||||
int endIdx = -1;
|
||||
if (aSortedRowArr.length >= 1)
|
||||
{
|
||||
begIdx = aSortedRowArr[0];
|
||||
endIdx = begIdx;
|
||||
}
|
||||
|
||||
if (aIgnoreListener != null)
|
||||
aTable.getSelectionModel().removeListSelectionListener(aIgnoreListener);
|
||||
|
||||
aTable.clearSelection();
|
||||
|
||||
for (int aRow : aSortedRowArr)
|
||||
{
|
||||
// Expand the range by: +1
|
||||
if (aRow == endIdx + 1)
|
||||
{
|
||||
endIdx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add the current interval
|
||||
aTable.addRowSelectionInterval(begIdx, endIdx);
|
||||
|
||||
// Start a new range
|
||||
begIdx = endIdx = aRow;
|
||||
}
|
||||
|
||||
// Ensure the last interval gets added
|
||||
if (begIdx != -1 && endIdx != -1)
|
||||
aTable.addRowSelectionInterval(begIdx, endIdx);
|
||||
|
||||
if (aIgnoreListener != null)
|
||||
aTable.getSelectionModel().addListSelectionListener(aIgnoreListener);
|
||||
}
|
||||
|
||||
}
|
||||
33
src/glum/gui/action/ActionComponentProvider.java
Normal file
33
src/glum/gui/action/ActionComponentProvider.java
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.action;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Interface that provides a mechanism for a component to declare that it will provide action {@link Component}s
|
||||
* (typically buttons).
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public interface ActionComponentProvider
|
||||
{
|
||||
|
||||
/**
|
||||
* Returns a list of {@link Component}s that should be placed in the action region.
|
||||
*/
|
||||
public Collection<? extends Component> getActionButtons();
|
||||
|
||||
}
|
||||
@@ -1,22 +1,44 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.action;
|
||||
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.AbstractButton;
|
||||
|
||||
/**
|
||||
* Action used to "click" on the target {@link AbstractButton}.
|
||||
* <p>
|
||||
* Clicking will be done via the {@link AbstractButton#doClick()} method.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class ClickAction extends AbstractAction
|
||||
{
|
||||
// State vars
|
||||
protected AbstractButton target;
|
||||
// Reference vars
|
||||
private final AbstractButton refTarget;
|
||||
|
||||
public ClickAction(AbstractButton aTarget)
|
||||
{
|
||||
target = aTarget;
|
||||
refTarget = aTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
target.doClick();
|
||||
refTarget.doClick();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
82
src/glum/gui/action/CloseDialog.java
Normal file
82
src/glum/gui/action/CloseDialog.java
Normal file
@@ -0,0 +1,82 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.action;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Frame;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
import glum.gui.GuiUtil;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* JDialog that holds a single {@link Component} and a close button.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class CloseDialog extends JDialog implements ActionListener
|
||||
{
|
||||
// Gui vars
|
||||
private final JButton closeB;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*/
|
||||
public CloseDialog(Frame aParent, Component aMainComp)
|
||||
{
|
||||
super(aParent);
|
||||
|
||||
var tmpPanel = new JPanel();
|
||||
tmpPanel.setLayout(new MigLayout("", "[]", "0[]0[]"));
|
||||
|
||||
tmpPanel.add(aMainComp, "growx,growy,pushx,pushy,span,wrap");
|
||||
|
||||
// Form a unified list of buttons
|
||||
var tmpActionCompL = new ArrayList<Component>();
|
||||
if (aMainComp instanceof ActionComponentProvider)
|
||||
tmpActionCompL.addAll(((ActionComponentProvider) aMainComp).getActionButtons());
|
||||
closeB = GuiUtil.formButton(this, "Close");
|
||||
tmpActionCompL.add(closeB);
|
||||
|
||||
// Add the components in
|
||||
var isFirst = true;
|
||||
for (Component aComp : tmpActionCompL)
|
||||
{
|
||||
if (isFirst == true)
|
||||
tmpPanel.add(aComp, "span,split,ax right");
|
||||
else
|
||||
tmpPanel.add(aComp, "");
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
setContentPane(tmpPanel);
|
||||
setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
|
||||
setModal(false);
|
||||
pack();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aEvent)
|
||||
{
|
||||
var source = aEvent.getSource();
|
||||
if (source == closeB)
|
||||
setVisible(false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,23 +1,55 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.action;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
|
||||
/**
|
||||
* Action used to change the target {@link Component} to be visible.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class MakeVisibleAction extends AbstractAction
|
||||
{
|
||||
// State vars
|
||||
protected Component target;
|
||||
// Reference vars
|
||||
private final Component refTarget;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aTarget
|
||||
*/
|
||||
public MakeVisibleAction(Component aTarget)
|
||||
{
|
||||
target = aTarget;
|
||||
refTarget = aTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reference target.
|
||||
*/
|
||||
public Component getTarget()
|
||||
{
|
||||
return refTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
target.setVisible(true);
|
||||
refTarget.setVisible(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
66
src/glum/gui/action/PopAction.java
Normal file
66
src/glum/gui/action/PopAction.java
Normal file
@@ -0,0 +1,66 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.action;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.JMenuItem;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
/**
|
||||
* Base action specific to popup menus.
|
||||
* <p>
|
||||
* Whenever the list of selected objects changes this PopAction will be notified.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public abstract class PopAction<G1> extends AbstractAction
|
||||
{
|
||||
// State vars
|
||||
private ImmutableList<G1> itemL;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*/
|
||||
public PopAction()
|
||||
{
|
||||
itemL = ImmutableList.of();
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification that the {@link PopAction} should be executed on the specified items.
|
||||
*
|
||||
* @param aItemL
|
||||
*/
|
||||
public abstract void executeAction(List<G1> aItemL);
|
||||
|
||||
/**
|
||||
* Sets in the items that are currently selected.
|
||||
*/
|
||||
public void setChosenItems(Collection<G1> aItemC, JMenuItem aAssocMI)
|
||||
{
|
||||
itemL = ImmutableList.copyOf(aItemC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aAction)
|
||||
{
|
||||
executeAction(itemL);
|
||||
}
|
||||
|
||||
}
|
||||
93
src/glum/gui/action/PopupMenu.java
Normal file
93
src/glum/gui/action/PopupMenu.java
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.action;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.JMenuItem;
|
||||
import javax.swing.JPopupMenu;
|
||||
|
||||
import glum.item.ItemManager;
|
||||
|
||||
/**
|
||||
* UI component that allows a custom popup menu to be built.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class PopupMenu<G1> extends JPopupMenu
|
||||
{
|
||||
// Reference vars
|
||||
private ItemManager<G1> refManager;
|
||||
|
||||
// State vars
|
||||
private Map<JMenuItem, PopAction<G1>> actionM;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aManager
|
||||
*/
|
||||
public PopupMenu(ItemManager<G1> aManager)
|
||||
{
|
||||
refManager = aManager;
|
||||
|
||||
actionM = new HashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the specified {@link PopAction} into this {@link PopupMenu}.
|
||||
* <p>
|
||||
* A simple menu item will be created and associated with the specified action.
|
||||
*/
|
||||
public void installPopAction(PopAction<G1> aAction, String aTitle)
|
||||
{
|
||||
JMenuItem tmpMI = new JMenuItem(aAction);
|
||||
tmpMI.setText(aTitle);
|
||||
|
||||
// Delegate
|
||||
installPopAction(aAction, tmpMI);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the specified {@link PopAction} into this {@link PopupMenu}.
|
||||
* <p>
|
||||
* The action will be associated with the specified menu item.
|
||||
*/
|
||||
public void installPopAction(PopAction<G1> aAction, JMenuItem aTargMI)
|
||||
{
|
||||
add(aTargMI);
|
||||
actionM.put(aTargMI, aAction);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void show(Component aParent, int aX, int aY)
|
||||
{
|
||||
// Bail if we do not have selected items
|
||||
Set<G1> tmpS = refManager.getSelectedItems();
|
||||
if (tmpS.size() == 0)
|
||||
return;
|
||||
|
||||
// Update our PopActions
|
||||
for (JMenuItem aMI : actionM.keySet())
|
||||
{
|
||||
PopAction<G1> tmpPA = actionM.get(aMI);
|
||||
tmpPA.setChosenItems(tmpS, aMI);
|
||||
}
|
||||
|
||||
// Delegate
|
||||
super.show(aParent, aX, aY);
|
||||
}
|
||||
|
||||
}
|
||||
80
src/glum/gui/component/GBaseTextField.java
Normal file
80
src/glum/gui/component/GBaseTextField.java
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
|
||||
/**
|
||||
* User interface input used to capture an input string.
|
||||
* <p>
|
||||
* This object provides the following additional features:
|
||||
* <ul>
|
||||
* <li>Display of passive hint text
|
||||
* </ul>
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GBaseTextField extends JTextField
|
||||
{
|
||||
// State vars
|
||||
private String mHint;
|
||||
|
||||
/** Standard Constructor */
|
||||
public GBaseTextField(String aText, int aNumColumns)
|
||||
{
|
||||
super(aText, aNumColumns);
|
||||
|
||||
mHint = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a hint that will be shown whenever the text field is empty.
|
||||
*/
|
||||
public void setHint(String aHint)
|
||||
{
|
||||
mHint = aHint;
|
||||
repaint();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paint(Graphics g)
|
||||
{
|
||||
super.paint(g);
|
||||
|
||||
// Bail if there is already input
|
||||
if (getText().length() != 0)
|
||||
return;
|
||||
|
||||
// Bail if there is no hint
|
||||
if (mHint == null || mHint.length() == 0)
|
||||
return;
|
||||
|
||||
// Draw the textual hint
|
||||
// Source:
|
||||
// https://stackoverflow.com/questions/1738966/java-jtextfield-with-input-hint
|
||||
int h = getHeight();
|
||||
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
|
||||
Insets ins = getInsets();
|
||||
FontMetrics fm = g.getFontMetrics();
|
||||
int c0 = getBackground().getRGB();
|
||||
int c1 = getForeground().getRGB();
|
||||
int m = 0xfefefefe;
|
||||
int c2 = ((c0 & m) >>> 1) + ((c1 & m) >>> 1);
|
||||
g.setColor(new Color(c2, true));
|
||||
g.drawString(mHint, ins.left, h / 2 + fm.getAscent() / 2 - 2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,58 +1,81 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import glum.gui.component.model.GComboBoxModel;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.ListCellRenderer;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import glum.gui.component.model.GComboBoxModel;
|
||||
|
||||
/**
|
||||
* Enhanced implementation of {@link JComboBox}. This implementation provides for better generics support. Please
|
||||
* utilize the {@link #getChosenItem()}, {@link #setChosenItem(Object)}, etc...
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GComboBox<G1> extends JComboBox<G1>
|
||||
{
|
||||
// State vars
|
||||
protected GComboBoxModel<G1> itemModel;
|
||||
|
||||
private GComboBoxModel<G1> itemModel;
|
||||
|
||||
public GComboBox()
|
||||
{
|
||||
itemModel = new GComboBoxModel<G1>(new LinkedList<G1>());
|
||||
itemModel = new GComboBoxModel<G1>(ImmutableList.of());
|
||||
setModel(itemModel);
|
||||
}
|
||||
|
||||
|
||||
public GComboBox(ActionListener aListener, ListCellRenderer<? super G1> aRenderer)
|
||||
{
|
||||
this();
|
||||
|
||||
|
||||
addActionListener(aListener);
|
||||
setRenderer(aRenderer);
|
||||
}
|
||||
|
||||
|
||||
public GComboBox(ActionListener aListener)
|
||||
{
|
||||
this();
|
||||
|
||||
|
||||
addActionListener(aListener);
|
||||
}
|
||||
|
||||
public GComboBox(ActionListener aListener, List<G1> aItemList)
|
||||
|
||||
public GComboBox(ActionListener aListener, Collection<G1> aItemC)
|
||||
{
|
||||
itemModel = new GComboBoxModel<G1>(aItemList);
|
||||
itemModel = new GComboBoxModel<>(aItemC);
|
||||
setModel(itemModel);
|
||||
|
||||
addActionListener(aListener);
|
||||
}
|
||||
|
||||
|
||||
public GComboBox(ActionListener aListener, G1... aItemArr)
|
||||
{
|
||||
itemModel = new GComboBoxModel<G1>(aItemArr);
|
||||
itemModel = new GComboBoxModel<>(aItemArr);
|
||||
setModel(itemModel);
|
||||
|
||||
|
||||
addActionListener(aListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all items stored in the GComboBox
|
||||
*/
|
||||
public ArrayList<G1> getAllItems()
|
||||
public List<G1> getAllItems()
|
||||
{
|
||||
return itemModel.getAllItems();
|
||||
}
|
||||
@@ -64,43 +87,43 @@ public class GComboBox<G1> extends JComboBox<G1>
|
||||
{
|
||||
return itemModel.getSelectedItem();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets in the currently selected item. This method will not trigger an ActionEvent.
|
||||
*
|
||||
* @see JComboBox#setSelectedItem
|
||||
*/
|
||||
public void setChosenItem(G1 aItem)
|
||||
{
|
||||
ActionListener[] listenerArr;
|
||||
|
||||
listenerArr = getActionListeners();
|
||||
var listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
|
||||
itemModel.setSelectedItem(aItem);
|
||||
super.setSelectedItem(aItem);
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
|
||||
// We must force a repaint since any ActionListener responsible will never get the update
|
||||
// We must force a repaint since any ActionListener responsible will never get the update
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Note aItem must be of the generified type. This method will not trigger an ActionEvent.
|
||||
*/
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addItem(Object aItem)
|
||||
{
|
||||
ActionListener[] listenerArr;
|
||||
|
||||
|
||||
listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
itemModel.addItem((G1)aItem);
|
||||
|
||||
|
||||
itemModel.addItem((G1) aItem);
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
}
|
||||
@@ -110,15 +133,29 @@ public class GComboBox<G1> extends JComboBox<G1>
|
||||
*/
|
||||
public void addItems(G1... aItemArr)
|
||||
{
|
||||
ActionListener[] listenerArr;
|
||||
|
||||
listenerArr = getActionListeners();
|
||||
var listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
|
||||
for (G1 aItem : aItemArr)
|
||||
itemModel.addItem(aItem);
|
||||
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all of the specified items to the model. This method will not trigger an ActionEvent.
|
||||
*/
|
||||
public void addItems(Collection<G1> aItemC)
|
||||
{
|
||||
var listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
for (G1 aItem : aItemC)
|
||||
itemModel.addItem(aItem);
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
}
|
||||
@@ -126,17 +163,68 @@ public class GComboBox<G1> extends JComboBox<G1>
|
||||
/**
|
||||
* Note aItem must be of the generified type. This method will not trigger an ActionEvent.
|
||||
*/
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void removeItem(Object aItem)
|
||||
{
|
||||
ActionListener[] listenerArr;
|
||||
|
||||
listenerArr = getActionListeners();
|
||||
var listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
itemModel.removeItem((G1)aItem);
|
||||
|
||||
|
||||
itemModel.removeItem((G1) aItem);
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to replace all of the items with the specified list of items.
|
||||
* <p>
|
||||
* If the current selection is in the replacement list then the selection will be maintained otherwise it will be
|
||||
* replaced with the first item in the list.
|
||||
* <p>
|
||||
* This method will not trigger an ActionEvent.
|
||||
*/
|
||||
public void replaceAllItems(Collection<G1> aItemC)
|
||||
{
|
||||
G1 pickItem = getChosenItem();
|
||||
|
||||
var listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
// Replace the items
|
||||
itemModel.removeAllItems();
|
||||
|
||||
for (G1 aItem : aItemC)
|
||||
itemModel.addItem(aItem);
|
||||
|
||||
// Update the selection after the replacement
|
||||
if (aItemC.contains(pickItem) == false)
|
||||
pickItem = null;
|
||||
if (pickItem == null && aItemC.size() > 0)
|
||||
pickItem = aItemC.iterator().next();
|
||||
|
||||
setChosenItem(pickItem);
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to replace the original item with the provided replacement.
|
||||
* <p>
|
||||
* This method will not trigger an ActionEvent.
|
||||
*/
|
||||
public void replaceItem(G1 aOrigItem, G1 aReplItem)
|
||||
{
|
||||
var listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
// Delegate
|
||||
itemModel.replaceItem(aOrigItem, aReplItem);
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
}
|
||||
@@ -147,14 +235,12 @@ public class GComboBox<G1> extends JComboBox<G1>
|
||||
@Override
|
||||
public void removeAllItems()
|
||||
{
|
||||
ActionListener[] listenerArr;
|
||||
|
||||
listenerArr = getActionListeners();
|
||||
var listenerArr = getActionListeners();
|
||||
for (ActionListener aListener : listenerArr)
|
||||
removeActionListener(aListener);
|
||||
|
||||
|
||||
itemModel.removeAllItems();
|
||||
|
||||
|
||||
for (ActionListener aListener : listenerArr)
|
||||
addActionListener(aListener);
|
||||
}
|
||||
@@ -166,7 +252,7 @@ public class GComboBox<G1> extends JComboBox<G1>
|
||||
// {
|
||||
// throw new RuntimeException("Unsupported operation. Call getChosenItem()");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// @Override
|
||||
// public void setSelectedItem(Object aObj)
|
||||
// {
|
||||
|
||||
@@ -1,32 +1,49 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import glum.gui.panel.generic.GenericCodes;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import glum.gui.panel.generic.GenericCodes;
|
||||
|
||||
/**
|
||||
* Base component that provides support for {@link ActionListener} event mechanism.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GComponent extends JComponent implements GenericCodes
|
||||
{
|
||||
// State vars
|
||||
protected List<ActionListener> myListeners;
|
||||
protected List<ActionListener> listenerL;
|
||||
|
||||
/** Standard Constructor */
|
||||
public GComponent()
|
||||
{
|
||||
super();
|
||||
|
||||
myListeners = Lists.newLinkedList();
|
||||
listenerL = new ArrayList<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add an ActionListener to this GPanel
|
||||
*/
|
||||
public void addActionListener(ActionListener aListener)
|
||||
{
|
||||
myListeners.add(aListener);
|
||||
listenerL.add(aListener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -34,16 +51,16 @@ public class GComponent extends JComponent implements GenericCodes
|
||||
*/
|
||||
public void removeActionListener(ActionListener aListener)
|
||||
{
|
||||
myListeners.remove(aListener);
|
||||
listenerL.remove(aListener);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send out notification to all of the ActionListeners
|
||||
*/
|
||||
public void notifyListeners(Object aSource, int aId, String aCommand)
|
||||
{
|
||||
for (ActionListener aListener : myListeners)
|
||||
for (var aListener : listenerL)
|
||||
aListener.actionPerformed(new ActionEvent(aSource, aId, aCommand));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,25 +1,37 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import glum.unit.UnitListener;
|
||||
import glum.unit.UnitProvider;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
public class GFancyLabel extends JLabel implements UnitListener
|
||||
{
|
||||
// State vars
|
||||
protected UnitProvider[] unitProviderArr;
|
||||
protected String[] formatStrArr;
|
||||
protected Object[] refValueArr;
|
||||
private UnitProvider[] unitProviderArr;
|
||||
private String[] formatStrArr;
|
||||
private Object[] refValueArr;
|
||||
|
||||
/**
|
||||
* Fancy JLabel which provides auto formatting of objects. The constructor
|
||||
* is provided with a formatStr which has unit place holders specified by "%u"
|
||||
* There must be a corresponding UnitProvider for each occurrence of "%u". This
|
||||
* is provided via the variable arguments of UnitProvider.
|
||||
* Fancy JLabel which provides auto formatting of objects. The constructor is provided with a formatStr which has
|
||||
* unit place holders specified by "%u" There must be a corresponding UnitProvider for each occurrence of "%u". This
|
||||
* is provided via the variable arguments of UnitProvider.
|
||||
*/
|
||||
public GFancyLabel(String formatStr, UnitProvider... aUnitProviderArr)
|
||||
{
|
||||
@@ -27,27 +39,25 @@ public class GFancyLabel extends JLabel implements UnitListener
|
||||
}
|
||||
|
||||
/**
|
||||
* Fancy JLabel which provides auto formatting of objects. The constructor
|
||||
* is provided with a formatStr which has unit place holders specified by "%u"
|
||||
* There must be a corresponding UnitProvider for each occurrence of "%u". This
|
||||
* is provided via the variable arguments of UnitProvider.
|
||||
* Fancy JLabel which provides auto formatting of objects. The constructor is provided with a formatStr which has
|
||||
* unit place holders specified by "%u" There must be a corresponding UnitProvider for each occurrence of "%u". This
|
||||
* is provided via the variable arguments of UnitProvider.
|
||||
*/
|
||||
public GFancyLabel(Font aFont, String aFormatStr, UnitProvider... aUnitProviderArr)
|
||||
{
|
||||
super();
|
||||
|
||||
if (aFont != null)
|
||||
setFont(aFont);
|
||||
|
||||
|
||||
formatStrArr = aFormatStr.split("%u", -1);
|
||||
|
||||
|
||||
unitProviderArr = aUnitProviderArr;
|
||||
for (UnitProvider aUnitProvider : unitProviderArr)
|
||||
aUnitProvider.addListener(this);
|
||||
|
||||
|
||||
// Insanity check
|
||||
if (unitProviderArr.length != formatStrArr.length - 1)
|
||||
throw new RuntimeException("Num place holders: " + (formatStrArr.length - 1) + " Num units: " + unitProviderArr.length);
|
||||
throw new RuntimeException(
|
||||
"Num place holders: " + (formatStrArr.length - 1) + " Num units: " + unitProviderArr.length);
|
||||
|
||||
refValueArr = new Object[unitProviderArr.length];
|
||||
for (int c1 = 0; c1 < unitProviderArr.length; c1++)
|
||||
@@ -63,31 +73,30 @@ public class GFancyLabel extends JLabel implements UnitListener
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to set in the set of values which will be formatted with the associated UnitProviders
|
||||
* which were specified via the constructor.
|
||||
* Method to set in the set of values which will be formatted with the associated UnitProviders which were specified
|
||||
* via the constructor.
|
||||
*/
|
||||
public void setValues(Object... aValueArr)
|
||||
{
|
||||
String aStr;
|
||||
|
||||
// Ensure the number of objects matches the number of units
|
||||
if (unitProviderArr.length != aValueArr.length)
|
||||
throw new RuntimeException("Inproper number of arguments. Expected: " + unitProviderArr.length + " Recieved:" + aValueArr.length);
|
||||
|
||||
throw new RuntimeException("Inproper number of arguments. Expected: " + unitProviderArr.length //
|
||||
+ " Recieved:" + aValueArr.length);
|
||||
|
||||
for (int c1 = 0; c1 < aValueArr.length; c1++)
|
||||
refValueArr[c1] = aValueArr[c1];
|
||||
|
||||
aStr = "";
|
||||
|
||||
var tmpStr = "";
|
||||
for (int c1 = 0; c1 < aValueArr.length; c1++)
|
||||
{
|
||||
aStr += formatStrArr[c1];
|
||||
aStr += unitProviderArr[c1].getUnit().getString(aValueArr[c1], false);
|
||||
tmpStr += formatStrArr[c1];
|
||||
tmpStr += unitProviderArr[c1].getUnit().getString(aValueArr[c1], false);
|
||||
}
|
||||
|
||||
if (formatStrArr.length > aValueArr.length)
|
||||
aStr += formatStrArr[formatStrArr.length - 1];
|
||||
|
||||
setText(aStr);
|
||||
if (formatStrArr.length > aValueArr.length)
|
||||
tmpStr += formatStrArr[formatStrArr.length - 1];
|
||||
|
||||
setText(tmpStr);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
|
||||
import glum.unit.ConstUnitProvider;
|
||||
import glum.unit.Unit;
|
||||
import glum.unit.UnitListener;
|
||||
import glum.unit.UnitProvider;
|
||||
|
||||
import javax.swing.JLabel;
|
||||
|
||||
import glum.unit.*;
|
||||
|
||||
public class GLabel extends JLabel implements UnitListener
|
||||
{
|
||||
// State vars
|
||||
@@ -34,8 +44,6 @@ public class GLabel extends JLabel implements UnitListener
|
||||
|
||||
public GLabel(UnitProvider aUnitProvider, Font aFont, boolean aShowLabel)
|
||||
{
|
||||
super();
|
||||
|
||||
refUnitProvider = aUnitProvider;
|
||||
if (refUnitProvider != null)
|
||||
refUnitProvider.addListener(this);
|
||||
@@ -62,9 +70,9 @@ public class GLabel extends JLabel implements UnitListener
|
||||
{
|
||||
String aStr;
|
||||
Unit aUnit;
|
||||
|
||||
|
||||
refValue = aValue;
|
||||
|
||||
|
||||
aUnit = null;
|
||||
if (refUnitProvider != null)
|
||||
aUnit = refUnitProvider.getUnit();
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.SwingUtilities;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
import glum.gui.component.model.GListModel;
|
||||
import glum.gui.panel.generic.GenericCodes;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
public class GList<G1> extends JComponent implements GenericCodes, ListSelectionListener
|
||||
{
|
||||
// Gui vars
|
||||
@@ -52,9 +60,7 @@ public class GList<G1> extends JComponent implements GenericCodes, ListSelection
|
||||
*/
|
||||
public G1 getSelectedItem()
|
||||
{
|
||||
int selectedIndex;
|
||||
|
||||
selectedIndex = refList.getSelectedIndex();
|
||||
var selectedIndex = refList.getSelectedIndex();
|
||||
if (selectedIndex == -1)
|
||||
return null;
|
||||
|
||||
@@ -66,17 +72,14 @@ public class GList<G1> extends JComponent implements GenericCodes, ListSelection
|
||||
*/
|
||||
public List<G1> getSelectedItems()
|
||||
{
|
||||
ArrayList<G1> retList;
|
||||
int[] indexArr;
|
||||
var indexArr = refList.getSelectedIndices();
|
||||
|
||||
indexArr = refList.getSelectedIndices();
|
||||
|
||||
retList = Lists.newArrayList();
|
||||
var retItemL = new ArrayList<G1>();
|
||||
for (int aIndex : indexArr)
|
||||
retList.add(refModel.getElementAt(aIndex));
|
||||
retItemL.add(refModel.getElementAt(aIndex));
|
||||
|
||||
retList.trimToSize();
|
||||
return retList;
|
||||
retItemL.trimToSize();
|
||||
return retItemL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,17 +107,14 @@ public class GList<G1> extends JComponent implements GenericCodes, ListSelection
|
||||
*/
|
||||
public void setSelectedItems(List<G1> aItemList)
|
||||
{
|
||||
int[] idArr;
|
||||
int c1;
|
||||
|
||||
// Ensure we are executed only on the proper thread
|
||||
if (SwingUtilities.isEventDispatchThread() == false)
|
||||
throw new RuntimeException("GList.selectItems() not executed on the AWT event dispatch thread.");
|
||||
|
||||
refList.removeListSelectionListener(this);
|
||||
|
||||
c1 = 0;
|
||||
idArr = new int[aItemList.size()];
|
||||
var c1 = 0;
|
||||
var idArr = new int[aItemList.size()];
|
||||
for (G1 aItem : aItemList)
|
||||
{
|
||||
idArr[c1] = refModel.indexOf(aItem);
|
||||
|
||||
@@ -1,56 +1,86 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.text.*;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.text.Document;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
import glum.gui.document.NumberDocument;
|
||||
import glum.unit.ConstUnitProvider;
|
||||
import glum.unit.NumberUnit;
|
||||
import glum.unit.Unit;
|
||||
import glum.unit.UnitListener;
|
||||
import glum.unit.UnitProvider;
|
||||
import glum.unit.*;
|
||||
|
||||
public class GNumberField extends JTextField implements DocumentListener, UnitListener
|
||||
/**
|
||||
* User interface input used to capture an individual numerical input (type: double).
|
||||
* <p>
|
||||
* Unlike JTextField, users of this class should not use getText() / setText() but rather getValue() / setValue()
|
||||
* methods. Also it should not be necessary to register DocumentListeners - rather an ActionListener should be
|
||||
* sufficient.
|
||||
* <p>
|
||||
* This class provides two modes of converting model values to textual input:
|
||||
* <ul>
|
||||
* <li>{@link NumberFormat} mechanism
|
||||
* <li>{@link UnitProvider} mechanism
|
||||
* </ul>
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GNumberField extends GBaseTextField implements DocumentListener, UnitListener
|
||||
{
|
||||
// Attributes
|
||||
private final NumberFormat refFormat;
|
||||
private final UnitProvider refUnitProvider;
|
||||
|
||||
// State vars
|
||||
protected UnitProvider refUnitProvider;
|
||||
protected double currValue, minValue, maxValue;
|
||||
protected boolean isMutating;
|
||||
private Range<Double> minMaxRange;
|
||||
private double currValue;
|
||||
private boolean isMutating;
|
||||
|
||||
// Gui vars
|
||||
protected Color failColor, passColor;
|
||||
protected NumberDocument myDocument;
|
||||
private Color colorFail, colorPass;
|
||||
private NumberDocument myDocument;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* : Default ActionListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aUnit
|
||||
* : Object used to format programatic entered values. Note aUnitProvider will also be used to determine if
|
||||
* Floating or only Integral input is allowed.
|
||||
* @param inputType
|
||||
* : Type of input to accept (Integer, Double, etc...)
|
||||
* @param aMinVal
|
||||
* : Minimum value to accept
|
||||
* @param aMaxVal
|
||||
* : Maximum value to accept
|
||||
* Object used to format programmatic entered values. Note aUnitProvider will also be used to determine if
|
||||
* Floating or only Integral input is allowed.
|
||||
* @param aMinMaxRange
|
||||
* The range of values to accept.
|
||||
*/
|
||||
public GNumberField(ActionListener aListener, UnitProvider aUnitProvider, double aMinVal, double aMaxVal)
|
||||
public GNumberField(ActionListener aListener, UnitProvider aUnitProvider, Range<Double> aMinMaxRange)
|
||||
{
|
||||
super("", 0);
|
||||
|
||||
refFormat = null;
|
||||
refUnitProvider = aUnitProvider;
|
||||
currValue = 0;
|
||||
minValue = aMinVal;
|
||||
maxValue = aMaxVal;
|
||||
|
||||
minMaxRange = aMinMaxRange;
|
||||
currValue = Double.NaN;
|
||||
isMutating = false;
|
||||
|
||||
failColor = Color.RED.darker();
|
||||
passColor = getForeground();
|
||||
colorFail = Color.RED.darker();
|
||||
colorPass = getForeground();
|
||||
|
||||
// Register the ActionListener
|
||||
if (aListener != null)
|
||||
@@ -69,31 +99,82 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
installUnit();
|
||||
}
|
||||
|
||||
public GNumberField(ActionListener aListener, Unit aUnit, double aMinVal, double aMaxVal)
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aFormat
|
||||
* NumberFormat used to transform the numerical value to a string.
|
||||
* @param aMinMaxRange
|
||||
* The range of values to accept.
|
||||
*/
|
||||
public GNumberField(ActionListener aListener, NumberFormat aFormat, Range<Double> aMinMaxRange)
|
||||
{
|
||||
this(aListener, new ConstUnitProvider(aUnit), aMinVal, aMaxVal);
|
||||
super("", 0);
|
||||
|
||||
refFormat = aFormat;
|
||||
refUnitProvider = null;
|
||||
|
||||
minMaxRange = aMinMaxRange;
|
||||
currValue = Double.NaN;
|
||||
isMutating = false;
|
||||
|
||||
colorFail = Color.RED.darker();
|
||||
colorPass = getForeground();
|
||||
|
||||
// Form the appropriate Document and initialize
|
||||
myDocument = new NumberDocument(this, false);
|
||||
super.setDocument(myDocument);
|
||||
|
||||
// Register the ActionListener
|
||||
if (aListener != null)
|
||||
addActionListener(aListener);
|
||||
|
||||
// Register for events of interest
|
||||
myDocument.addDocumentListener(this);
|
||||
|
||||
// Force the UI component to reflect the currValue. Note this is done last since this method
|
||||
// assumes the GNumberField is already registered with myDocument.
|
||||
forceTF(currValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current input is valid
|
||||
* Simplified Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aUnit
|
||||
* @param aMinMaxRange
|
||||
* The range of values to accept.
|
||||
*/
|
||||
public boolean isValidInput()
|
||||
public GNumberField(ActionListener aListener, Unit aUnit, Range<Double> aMinMaxRange)
|
||||
{
|
||||
Unit aUnit;
|
||||
double modelVal;
|
||||
this(aListener, new ConstUnitProvider(aUnit), aMinMaxRange);
|
||||
}
|
||||
|
||||
// Ensure we have valid input
|
||||
aUnit = refUnitProvider.getUnit();
|
||||
/**
|
||||
* Simplified Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aFormat
|
||||
* NumberFormat used to transform the numerical value to a string.
|
||||
*/
|
||||
public GNumberField(ActionListener aListener, NumberFormat aFormat)
|
||||
{
|
||||
this(aListener, aFormat, Range.closed(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
|
||||
}
|
||||
|
||||
modelVal = aUnit.parseString(this.getText(), Double.NaN);
|
||||
if (Double.isNaN(modelVal) == true)
|
||||
return false;
|
||||
|
||||
// Ensure the value is within range
|
||||
if (modelVal < minValue || modelVal > maxValue)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
/**
|
||||
* Simplified Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
*/
|
||||
public GNumberField(ActionListener aListener)
|
||||
{
|
||||
this(aListener, new DecimalFormat("#.###"), Range.closed(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,6 +191,30 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
myDocument.addDocumentListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Color} used to change foreground text whenever invalid input is entered.
|
||||
*/
|
||||
public Color getColorFail()
|
||||
{
|
||||
return colorFail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link Color} used to change foreground text whenever valid input is entered.
|
||||
*/
|
||||
public Color getColorPass()
|
||||
{
|
||||
return colorPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the range of valid values.
|
||||
*/
|
||||
public Range<Double> getMinMaxRange()
|
||||
{
|
||||
return minMaxRange;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently stored model value
|
||||
*/
|
||||
@@ -120,20 +225,65 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
|
||||
/**
|
||||
* Returns the currently stored model value as an integer. If the modelValue is NaN, then errorVal will be returned.
|
||||
* The values MaxInt, MinInt are returned for Infinity.
|
||||
* The values MAX_VALUE will be returned for +Infinity. The value MIN_VALUE will be returned for -Infinity.
|
||||
*/
|
||||
public int getValueAsInt(int errorVal)
|
||||
public long getValueAsLong(long aErrorVal)
|
||||
{
|
||||
if (Double.isNaN(currValue) == true)
|
||||
return errorVal;
|
||||
return aErrorVal;
|
||||
|
||||
return (int)currValue;
|
||||
return (long) currValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently stored model value as an integer. If the modelValue is NaN, then errorVal will be returned.
|
||||
* The values MAX_VALUE will be returned for +Infinity. The value MIN_VALUE will be returned for -Infinity.
|
||||
*/
|
||||
public int getValueAsInt(int aErrorVal)
|
||||
{
|
||||
if (Double.isNaN(currValue) == true)
|
||||
return aErrorVal;
|
||||
|
||||
return (int) currValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current input is valid
|
||||
*/
|
||||
public boolean isValidInput()
|
||||
{
|
||||
// Ensure we have valid input
|
||||
double modelVal = transformToModel(this.getText());
|
||||
if (Double.isNaN(modelVal) == true)
|
||||
return false;
|
||||
|
||||
// Ensure the value is within range
|
||||
if (minMaxRange.contains(modelVal) == false)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Color} used to indicate invalid input is entered.
|
||||
*/
|
||||
public void setColorFail(Color aColor)
|
||||
{
|
||||
colorFail = aColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Color} used to indicate valid input is entered.
|
||||
*/
|
||||
public void setColorPass(Color aColor)
|
||||
{
|
||||
colorPass = aColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes in a model value and will display it with respect to the active unit. This method will not trigger an
|
||||
* ActionEvent.
|
||||
* <P>
|
||||
* <p>
|
||||
* Note this method will do nothing if the UI is being "mutated" when this method is called.
|
||||
*/
|
||||
public void setValue(final double aValue)
|
||||
@@ -143,6 +293,16 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
if (isMutating == true)
|
||||
return;
|
||||
|
||||
// Bail if the value has not changed. We do this so that user
|
||||
// entered input will not change if the model value has not changed.
|
||||
double ulp = Math.ulp(aValue);
|
||||
boolean ignoreInput = true;
|
||||
ignoreInput &= Double.isNaN(ulp) == false;
|
||||
ignoreInput &= Double.isFinite(ulp) == true;
|
||||
ignoreInput &= Math.abs(currValue - aValue) < ulp;
|
||||
if (ignoreInput == true)
|
||||
return;
|
||||
|
||||
// Simple edit if we are not currently being mutated
|
||||
forceTF(aValue);
|
||||
updateGui();
|
||||
@@ -151,28 +311,26 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
/**
|
||||
* Changes the range of acceptable values (in model units). Note the current value will be force to fit this range.
|
||||
*/
|
||||
public void setMinMaxValue(double aMinValue, double aMaxValue)
|
||||
public void setMinMaxRange(Range<Double> aMinMaxRange)
|
||||
{
|
||||
Unit aUnit;
|
||||
|
||||
minValue = aMinValue;
|
||||
maxValue = aMaxValue;
|
||||
if (currValue < minValue || currValue > maxValue)
|
||||
currValue = minValue;
|
||||
minMaxRange = aMinMaxRange;
|
||||
if (minMaxRange.hasLowerBound() == true && currValue < minMaxRange.lowerEndpoint())
|
||||
currValue = minMaxRange.lowerEndpoint();
|
||||
else if (minMaxRange.hasUpperBound() == true && currValue > minMaxRange.upperEndpoint())
|
||||
currValue = minMaxRange.upperEndpoint();
|
||||
|
||||
// Update our document
|
||||
aUnit = refUnitProvider.getUnit();
|
||||
myDocument.setMinMaxValue(aUnit.toUnit(minValue), aUnit.toUnit(maxValue));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(Document aDoc)
|
||||
{
|
||||
// throw new UnsupportedOperationException();
|
||||
if (aDoc != null)
|
||||
aDoc.addDocumentListener(this);
|
||||
|
||||
super.setDocument(aDoc);
|
||||
double minValue = minMaxRange.lowerEndpoint();
|
||||
double maxValue = minMaxRange.upperEndpoint();
|
||||
if (refUnitProvider != null)
|
||||
{
|
||||
Unit tmpUnit = refUnitProvider.getUnit();
|
||||
myDocument.setMinMaxValue(tmpUnit.toUnit(minValue), tmpUnit.toUnit(maxValue));
|
||||
}
|
||||
else
|
||||
{
|
||||
myDocument.setMinMaxValue(minValue, maxValue);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,6 +351,16 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
syncValue(aEvent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDocument(Document aDoc)
|
||||
{
|
||||
// throw new UnsupportedOperationException();
|
||||
if (aDoc != null)
|
||||
aDoc.addDocumentListener(this);
|
||||
|
||||
super.setDocument(aDoc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unitChanged(UnitProvider aProvider, String aKey)
|
||||
{
|
||||
@@ -204,14 +372,11 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
*/
|
||||
protected void forceTF(double aValue)
|
||||
{
|
||||
Unit aUnit;
|
||||
String aStr;
|
||||
|
||||
// Save off the new model value, and check the validity
|
||||
currValue = aValue;
|
||||
if (currValue < minValue || currValue > maxValue)
|
||||
if (minMaxRange.contains(currValue) == false)
|
||||
currValue = Double.NaN;
|
||||
// throw new RuntimeException("Programatic input is invalid. Is unit compatible? Input: " + aValue);
|
||||
// throw new RuntimeException("Programmatic input is invalid. Is unit compatible? Input: " + aValue);
|
||||
|
||||
// Invalid values shall just clear the text field and bail
|
||||
if (Double.isNaN(currValue) == true)
|
||||
@@ -220,13 +385,12 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert from model value to (unit) textual format
|
||||
aUnit = refUnitProvider.getUnit();
|
||||
aStr = aUnit.getString(currValue);
|
||||
// Convert from model value to text
|
||||
String tmpStr = transformToString(currValue);
|
||||
|
||||
// Update the GUI internals
|
||||
myDocument.removeDocumentListener(this);
|
||||
setText(aStr);
|
||||
setText(tmpStr);
|
||||
setCaretPosition(0);
|
||||
myDocument.addDocumentListener(this);
|
||||
}
|
||||
@@ -236,20 +400,17 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
*/
|
||||
protected void installUnit()
|
||||
{
|
||||
Unit aUnit;
|
||||
boolean aBool;
|
||||
|
||||
// Ensure that we have a valid Unit
|
||||
aUnit = refUnitProvider.getUnit();
|
||||
if (aUnit instanceof NumberUnit == false)
|
||||
throw new RuntimeException("refUnitProvider must return a Unit of type NumberUnit. Unit: " + aUnit);
|
||||
Unit tmpUnit = refUnitProvider.getUnit();
|
||||
if (tmpUnit instanceof NumberUnit == false)
|
||||
throw new RuntimeException("refUnitProvider must return a Unit of type NumberUnit. Unit: " + tmpUnit);
|
||||
|
||||
// Update our Document to reflect whether this Unit supports floating point numbers
|
||||
aBool = (aUnit instanceof NumberUnit) && (((NumberUnit)aUnit).isFloating() == true);
|
||||
myDocument.setAllowFloats(aBool);
|
||||
boolean tmpBool = (tmpUnit instanceof NumberUnit) && (((NumberUnit) tmpUnit).isFloating() == true);
|
||||
myDocument.setAllowFloats(tmpBool);
|
||||
|
||||
// Update the Document's MinMax values reflect the new Unit
|
||||
setMinMaxValue(minValue, maxValue);
|
||||
setMinMaxRange(minMaxRange);
|
||||
|
||||
// Force myDocument's text to match the new unit
|
||||
forceTF(currValue);
|
||||
@@ -258,19 +419,16 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
/**
|
||||
* Keeps the "model" value conceptually linked to the GUI component. It will also trigger the actionEventListeners.
|
||||
*/
|
||||
protected void syncValue(DocumentEvent e)
|
||||
protected void syncValue(DocumentEvent aEvent)
|
||||
{
|
||||
Unit aUnit;
|
||||
|
||||
// Mark ourself as mutating
|
||||
isMutating = true;
|
||||
|
||||
// Convert the textual (unit) value to the model value
|
||||
aUnit = refUnitProvider.getUnit();
|
||||
currValue = aUnit.parseString(this.getText(), Double.NaN);
|
||||
// Convert the string to the model value
|
||||
currValue = transformToModel(this.getText());
|
||||
|
||||
// If the value is not in range then, it is invalid
|
||||
if (currValue < minValue || currValue > maxValue)
|
||||
if (minMaxRange.contains(currValue) == false)
|
||||
currValue = Double.NaN;
|
||||
|
||||
// Notify our listeners and update the GUI
|
||||
@@ -286,13 +444,55 @@ public class GNumberField extends JTextField implements DocumentListener, UnitLi
|
||||
*/
|
||||
protected void updateGui()
|
||||
{
|
||||
Color aColor;
|
||||
|
||||
aColor = passColor;
|
||||
Color tmpColor = colorPass;
|
||||
if (isValidInput() == false)
|
||||
aColor = failColor;
|
||||
tmpColor = colorFail;
|
||||
|
||||
setForeground(aColor);
|
||||
setForeground(tmpColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that will take a given value and convert it to a string.
|
||||
*
|
||||
* @param aValue
|
||||
*/
|
||||
private String transformToString(double aValue)
|
||||
{
|
||||
// Convert from model value to (unit) textual format
|
||||
if (refUnitProvider != null)
|
||||
{
|
||||
Unit tmpUnit = refUnitProvider.getUnit();
|
||||
String tmpStr = tmpUnit.getString(aValue);
|
||||
return tmpStr;
|
||||
}
|
||||
|
||||
return refFormat.format(aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that will take a String and convert it to the equivalent numerical value. On failure Double.NaN will
|
||||
* be returned.
|
||||
*
|
||||
* @param aValue
|
||||
*/
|
||||
private double transformToModel(String aStr)
|
||||
{
|
||||
// Convert the textual (unit) value to the model value
|
||||
if (refUnitProvider != null)
|
||||
{
|
||||
Unit tmpUnit = refUnitProvider.getUnit();
|
||||
double retValue = tmpUnit.parseString(aStr, Double.NaN);
|
||||
return retValue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Double.parseDouble(aStr);
|
||||
}
|
||||
catch (NumberFormatException aExp)
|
||||
{
|
||||
return Double.NaN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
218
src/glum/gui/component/GNumberFieldSlider.java
Normal file
218
src/glum/gui/component/GNumberFieldSlider.java
Normal file
@@ -0,0 +1,218 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import javax.swing.JPanel;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
import glum.gui.GuiUtil;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* User interface component that combines a {@link GNumberField} and a {@link GSlider} into a single unified component.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GNumberFieldSlider extends JPanel implements ActionListener
|
||||
{
|
||||
// Ref vars
|
||||
private final ActionListener refLister;
|
||||
|
||||
// Gui vars
|
||||
private GNumberField valueNF;
|
||||
private GSlider valueS;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aFormat
|
||||
* NumberFormat used to transform the numerical value to a string.
|
||||
* @param aMinMaxRange
|
||||
* The range of values to accept.
|
||||
* @param aNumColumns
|
||||
* The number of columns associated with the {@link GNumberField}.
|
||||
*/
|
||||
public GNumberFieldSlider(ActionListener aListener, NumberFormat aFormat, Range<Double> aMinMaxRange,
|
||||
int aNumColumns)
|
||||
{
|
||||
refLister = aListener;
|
||||
|
||||
buildGui(aFormat, aMinMaxRange);
|
||||
|
||||
setNumColumns(aNumColumns);
|
||||
setNumSteps(100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aFormat
|
||||
* NumberFormat used to transform the numerical value to a string.
|
||||
* @param aMinMaxRange
|
||||
* The range of values to accept.
|
||||
*/
|
||||
public GNumberFieldSlider(ActionListener aListener, NumberFormat aFormat, Range<Double> aMinMaxRange)
|
||||
{
|
||||
this(aListener, aFormat, aMinMaxRange, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the current input is valid
|
||||
*/
|
||||
public boolean isValidInput()
|
||||
{
|
||||
// Delegate
|
||||
return valueNF.isValidInput();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the selected value.
|
||||
*/
|
||||
public double getValue()
|
||||
{
|
||||
return valueNF.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently stored model value as an integer.
|
||||
* <p>
|
||||
* See {@link GNumberField#getValueAsInt(int)}
|
||||
*/
|
||||
public int getValueAsInt(int aErrorVal)
|
||||
{
|
||||
return valueNF.getValueAsInt(aErrorVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the value is being actively adjusted.
|
||||
* <p>
|
||||
* See also {@link GSlider#getValueIsAdjusting()}
|
||||
*/
|
||||
public boolean getValueIsAdjusting()
|
||||
{
|
||||
// Delegate
|
||||
return valueS.getValueIsAdjusting();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets in the selected value. Note no events will be fired.
|
||||
*/
|
||||
public void setValue(double aVal)
|
||||
{
|
||||
valueNF.setValue(aVal);
|
||||
valueS.setModelValue(aVal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the editable state of the UI component.
|
||||
*/
|
||||
public void setEditable(boolean aBool)
|
||||
{
|
||||
valueNF.setEditable(aBool);
|
||||
valueS.setEnabled(aBool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the enable state of the UI component.
|
||||
*/
|
||||
@Override
|
||||
public void setEnabled(boolean aBool)
|
||||
{
|
||||
GuiUtil.setEnabled(this, aBool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets in the steps to be an integral value.
|
||||
* <p>
|
||||
* The minVal and maxVal must be integers otherwise this method will throw an exception. The number of steps will be:
|
||||
* (maxVal - minVal).
|
||||
*/
|
||||
public void setIntegralSteps()
|
||||
{
|
||||
var tmpMinMaxRange = valueNF.getMinMaxRange();
|
||||
double tmpMinVal = tmpMinMaxRange.lowerEndpoint();
|
||||
double tmpMaxVal = tmpMinMaxRange.upperEndpoint();
|
||||
|
||||
int intMaxVal = (int) tmpMaxVal;
|
||||
int intMinVal = (int) tmpMinVal;
|
||||
|
||||
var isIntegral = true;
|
||||
isIntegral &= tmpMinVal - intMinVal == 0;
|
||||
isIntegral &= tmpMaxVal - intMaxVal == 0;
|
||||
if (isIntegral == false)
|
||||
throw new RuntimeException("Min,Max values are not integral: [" + tmpMinVal + ", " + tmpMaxVal + "]");
|
||||
|
||||
// Delegate
|
||||
int numSteps = intMaxVal - intMinVal;
|
||||
setNumSteps(numSteps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets in the number of columns for the associated GTextField.
|
||||
*/
|
||||
public void setNumColumns(int aNumColumns)
|
||||
{
|
||||
valueNF.setColumns(aNumColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets in the number of steps associated with the slider.
|
||||
*/
|
||||
public void setNumSteps(int aNumSteps)
|
||||
{
|
||||
valueS.setNumSteps(aNumSteps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent aEvent)
|
||||
{
|
||||
var source = aEvent.getSource();
|
||||
if (source == valueNF)
|
||||
{
|
||||
double tmpVal = valueNF.getValue();
|
||||
valueS.setModelValue(tmpVal);
|
||||
}
|
||||
else if (source == valueS)
|
||||
{
|
||||
double tmpVal = valueS.getModelValue();
|
||||
valueNF.setValue(tmpVal);
|
||||
}
|
||||
|
||||
var tmpEvent = new ActionEvent(this, 0, "");
|
||||
refLister.actionPerformed(tmpEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that builds the unified GUI
|
||||
*/
|
||||
private void buildGui(NumberFormat aNumberFormat, Range<Double> aMinMaxRange)
|
||||
{
|
||||
valueNF = new GNumberField(this, aNumberFormat, aMinMaxRange);
|
||||
valueS = new GSlider(this, aMinMaxRange);
|
||||
|
||||
setLayout(new MigLayout("", "0[]0", "0[]0"));
|
||||
add(valueNF, "w 40:");
|
||||
add(valueS, "growx,pushx");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
@@ -1,46 +1,91 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
import javax.swing.JSlider;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
import com.google.common.collect.Range;
|
||||
|
||||
/**
|
||||
* User interface input used to capture an individual numerical input (type: double).
|
||||
* <p>
|
||||
* Unlike JSlider, users of this class should not use getValue() / setValue() but rather getModelValue() /
|
||||
* setModelValue() methods. Also it should not be necessary to register ChangeListeners - rather an ActionListener
|
||||
* should be sufficient.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GSlider extends JSlider implements ChangeListener
|
||||
{
|
||||
private ActionListener myListener;
|
||||
private double minVal, maxVal, rngVal;
|
||||
// Attributes
|
||||
private final ActionListener refListener;
|
||||
|
||||
// State vars
|
||||
private Range<Double> minMaxRange;
|
||||
private int maxSteps;
|
||||
|
||||
public GSlider(ActionListener aListener, int aMaxSteps, double aMinVal, double aMaxVal)
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aMinMaxRange
|
||||
* The range of values to accept.
|
||||
* @param aMaxSteps
|
||||
* The number of steps associated with the slider.
|
||||
*/
|
||||
public GSlider(ActionListener aListener, Range<Double> aMinMaxRange, int aMaxSteps)
|
||||
{
|
||||
super(0, aMaxSteps);
|
||||
addChangeListener(this);
|
||||
|
||||
myListener = aListener;
|
||||
refListener = aListener;
|
||||
|
||||
minMaxRange = aMinMaxRange;
|
||||
maxSteps = aMaxSteps;
|
||||
|
||||
minVal = aMinVal;
|
||||
maxVal = aMaxVal;
|
||||
rngVal = maxVal - minVal;
|
||||
}
|
||||
|
||||
public GSlider(ActionListener aListener, double aMinVal, double aMaxVal)
|
||||
/**
|
||||
* Simplified Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aMinMaxRange
|
||||
* The range of values to accept.
|
||||
*/
|
||||
public GSlider(ActionListener aListener, Range<Double> aMinMaxRange)
|
||||
{
|
||||
this(aListener, 1000, aMinVal, aMaxVal);
|
||||
this(aListener, aMinMaxRange, 1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the model value for which this slider is currently set to.
|
||||
* <P>
|
||||
* <p>
|
||||
* Use this method over {@link JSlider#getValue()}
|
||||
*/
|
||||
public double getModelValue()
|
||||
{
|
||||
double retVal;
|
||||
double minVal = minMaxRange.lowerEndpoint();
|
||||
double maxVal = minMaxRange.upperEndpoint();
|
||||
double rngVal = maxVal - minVal;
|
||||
|
||||
retVal = minVal + ((super.getValue() / (double)maxSteps) * rngVal);
|
||||
double retVal = minVal + ((super.getValue() / (double) maxSteps) * rngVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@@ -48,11 +93,13 @@ public class GSlider extends JSlider implements ChangeListener
|
||||
* Takes in the model's minVal and maxVal range. The current chosen model value will be adjusted to be in the middle
|
||||
* of the range.
|
||||
*/
|
||||
public void setModelRange(double aMinVal, double aMaxVal)
|
||||
public void setModelRange(Range<Double> aMinMaxRange)
|
||||
{
|
||||
minVal = aMinVal;
|
||||
maxVal = aMaxVal;
|
||||
rngVal = maxVal - minVal;
|
||||
minMaxRange = aMinMaxRange;
|
||||
|
||||
double minVal = minMaxRange.lowerEndpoint();
|
||||
double maxVal = minMaxRange.upperEndpoint();
|
||||
double rngVal = maxVal - minVal;
|
||||
|
||||
setModelValue(minVal + rngVal / 2);
|
||||
}
|
||||
@@ -60,17 +107,37 @@ public class GSlider extends JSlider implements ChangeListener
|
||||
/**
|
||||
* Takes in a model value and will adjust the slider to display the value. Note this method will not trigger an
|
||||
* ActionEvent.
|
||||
* <P>
|
||||
* <p>
|
||||
* Use this method over {@link JSlider#setValue}
|
||||
*/
|
||||
public void setModelValue(double aVal)
|
||||
{
|
||||
double guiVal;
|
||||
|
||||
guiVal = ((aVal - minVal) / rngVal) * maxSteps;
|
||||
double minVal = minMaxRange.lowerEndpoint();
|
||||
double maxVal = minMaxRange.upperEndpoint();
|
||||
double rngVal = maxVal - minVal;
|
||||
|
||||
removeChangeListener(this);
|
||||
setValue((int)guiVal);
|
||||
double guiVal = ((aVal - minVal) / rngVal) * maxSteps;
|
||||
setValue((int) guiVal);
|
||||
addChangeListener(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets in the number of steps associated with the GSlider.
|
||||
* <p>
|
||||
* Values will be uniformly distributed over the range / numSteps
|
||||
*
|
||||
* @param aNumSteps
|
||||
* The number of steps the slider should have.
|
||||
*/
|
||||
public void setNumSteps(int aNumSteps)
|
||||
{
|
||||
removeChangeListener(this);
|
||||
|
||||
setMinimum(0);
|
||||
setMaximum(aNumSteps);
|
||||
maxSteps = aNumSteps;
|
||||
|
||||
addChangeListener(this);
|
||||
}
|
||||
|
||||
@@ -80,12 +147,26 @@ public class GSlider extends JSlider implements ChangeListener
|
||||
notifyLisener();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public int getValue()
|
||||
{
|
||||
return super.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setValue(int n)
|
||||
{
|
||||
super.setValue(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to notify our listener
|
||||
*/
|
||||
private void notifyLisener()
|
||||
{
|
||||
myListener.actionPerformed(new ActionEvent(this, 0, "update"));
|
||||
refListener.actionPerformed(new ActionEvent(this, 0, "update"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,49 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
public class GTextField extends JTextField implements DocumentListener
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.PlainDocument;
|
||||
|
||||
/**
|
||||
* User interface input used to capture an input string.
|
||||
* <p>
|
||||
* Unlike JTextField, users of this class should not use getText() / setText() but rather getValue() / setValue()
|
||||
* methods. Also it should not be necessary to register DocumentListeners - rather an ActionListener should be
|
||||
* sufficient.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GTextField extends GBaseTextField implements DocumentListener
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* : Default ActionListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aLabel
|
||||
* The text value to use as the initial input.
|
||||
* @param aHint
|
||||
* The hint to show when no input has been entered.
|
||||
*/
|
||||
public GTextField(ActionListener aListener)
|
||||
public GTextField(ActionListener aListener, String aLabel, String aHint)
|
||||
{
|
||||
super("", 0);
|
||||
super(aLabel, 0);
|
||||
|
||||
if (aListener != null)
|
||||
addActionListener(aListener);
|
||||
@@ -27,6 +55,35 @@ public class GTextField extends JTextField implements DocumentListener
|
||||
|
||||
// Register for events of interest
|
||||
doc.addDocumentListener(this);
|
||||
|
||||
if (aHint != null)
|
||||
setHint(aHint);
|
||||
|
||||
forceTF(aLabel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
* @param aLabel
|
||||
* The text value to use as the initial input.
|
||||
*/
|
||||
public GTextField(ActionListener aListener, String aLabel)
|
||||
{
|
||||
this(aListener, aLabel, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified Constructor
|
||||
*
|
||||
* @param aListener
|
||||
* An ActionListener that will be notified when ever the user makes any input changes.
|
||||
*/
|
||||
public GTextField(ActionListener aListener)
|
||||
{
|
||||
this(aListener, "", null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
package glum.gui.component;
|
||||
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JToggleButton;
|
||||
|
||||
public class GToggle extends JToggleButton
|
||||
{
|
||||
// State vars
|
||||
protected boolean isActive;
|
||||
|
||||
// Gui vars
|
||||
protected Icon falseIcon, trueIcon;
|
||||
|
||||
public GToggle(Icon aFalseIcon, Icon aTrueIcon, boolean aIsActive)
|
||||
{
|
||||
super();
|
||||
|
||||
falseIcon = aFalseIcon;
|
||||
trueIcon = aTrueIcon;
|
||||
setSelected(aIsActive);
|
||||
|
||||
setModel(new GToggleButtonModel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean b)
|
||||
{
|
||||
super.setSelected(b);
|
||||
updateGui();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doClick(int pressTime)
|
||||
{
|
||||
super.doClick(pressTime);
|
||||
updateGui();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method
|
||||
*/
|
||||
private void updateGui()
|
||||
{
|
||||
if (isSelected() == true)
|
||||
setIcon(trueIcon);
|
||||
else
|
||||
setIcon(falseIcon);
|
||||
}
|
||||
|
||||
/**
|
||||
* The ToggleButton model
|
||||
* <p>
|
||||
* <strong>Warning:</strong> Serialized objects of this class will not be compatible with future Swing releases. The
|
||||
* current serialization support is appropriate for short term storage or RMI between applications running the same
|
||||
* version of Swing. As of 1.4, support for long term storage of all JavaBeans<sup><font size="-2">TM</font></sup>
|
||||
* has been added to the <code>java.beans</code> package. Please see {@link java.beans.XMLEncoder}.
|
||||
*/
|
||||
public class GToggleButtonModel extends ToggleButtonModel
|
||||
{
|
||||
/**
|
||||
* Creates a new ToggleButton Model
|
||||
*/
|
||||
public GToggleButtonModel()
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean b)
|
||||
{
|
||||
super.setSelected(b);
|
||||
|
||||
updateGui();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,25 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component.banner;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.geom.*;
|
||||
import java.util.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.util.Collection;
|
||||
|
||||
import glum.gui.*;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import glum.io.ParseUtil;
|
||||
import glum.io.token.MatchTokenizer;
|
||||
import glum.io.token.Tokenizer;
|
||||
|
||||
@@ -37,7 +51,7 @@ public class Banner extends JComponent
|
||||
double sX, sY, offSetY;
|
||||
|
||||
super.paintComponent(g);
|
||||
g2d = (Graphics2D)g;
|
||||
g2d = (Graphics2D) g;
|
||||
|
||||
// Determine the window boundaries
|
||||
winW = getWidth();
|
||||
@@ -72,7 +86,7 @@ public class Banner extends JComponent
|
||||
sY = winH / 2.0 - msgH / 2.0;
|
||||
g2d.setFont(myConfig.font);
|
||||
g2d.setColor(myConfig.fgColor);
|
||||
g2d.drawString(displayMsg, (int)sX, (int)(sY + offSetY));
|
||||
g2d.drawString(displayMsg, (int) sX, (int) (sY + offSetY));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -102,8 +116,8 @@ public class Banner extends JComponent
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method that converts a string to a BannerConfig. Eventually this method class should be
|
||||
* moved to a utility class of sorts.
|
||||
* Utility method that converts a string to a BannerConfig. Eventually this method class should be moved to a utility
|
||||
* class of sorts.
|
||||
*/
|
||||
public static BannerConfig readBannerConfig(String strLine)
|
||||
{
|
||||
@@ -128,7 +142,7 @@ public class Banner extends JComponent
|
||||
for (String aInstr : instrSet)
|
||||
{
|
||||
parmSet = parmTokenizer.getTokens(aInstr);
|
||||
parms = parmSet.toArray(new String[] {""});
|
||||
parms = parmSet.toArray(new String[] { "" });
|
||||
|
||||
if (parms.length == 0)
|
||||
{
|
||||
@@ -152,15 +166,15 @@ public class Banner extends JComponent
|
||||
|
||||
size = 12;
|
||||
if (parms.length > 2)
|
||||
size = GuiUtil.readInt(parms[2], 12);
|
||||
size = ParseUtil.readInt(parms[2], 12);
|
||||
|
||||
bold = false;
|
||||
if (parms.length > 3)
|
||||
bold = GuiUtil.readBoolean(parms[3], false);
|
||||
bold = ParseUtil.readBoolean(parms[3], false);
|
||||
|
||||
italic = false;
|
||||
if (parms.length > 4)
|
||||
italic = GuiUtil.readBoolean(parms[4], false);
|
||||
italic = ParseUtil.readBoolean(parms[4], false);
|
||||
|
||||
style = 0;
|
||||
if (bold == false && italic == false)
|
||||
@@ -176,22 +190,22 @@ public class Banner extends JComponent
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
r = GuiUtil.readRangeInt(parms[1], 0, 255, 255);
|
||||
g = GuiUtil.readRangeInt(parms[2], 0, 255, 255);
|
||||
b = GuiUtil.readRangeInt(parms[3], 0, 255, 255);
|
||||
r = ParseUtil.readRangeInt(parms[1], 0, 255, 255);
|
||||
g = ParseUtil.readRangeInt(parms[2], 0, 255, 255);
|
||||
b = ParseUtil.readRangeInt(parms[3], 0, 255, 255);
|
||||
aConfig.fgColor = new Color(r, g, b);
|
||||
}
|
||||
else if (parms[0].equalsIgnoreCase("bgColor") == true && parms.length >= 4)
|
||||
{
|
||||
int r, g, b, a;
|
||||
|
||||
r = GuiUtil.readRangeInt(parms[1], 0, 255, 255);
|
||||
g = GuiUtil.readRangeInt(parms[2], 0, 255, 255);
|
||||
b = GuiUtil.readRangeInt(parms[3], 0, 255, 255);
|
||||
r = ParseUtil.readRangeInt(parms[1], 0, 255, 255);
|
||||
g = ParseUtil.readRangeInt(parms[2], 0, 255, 255);
|
||||
b = ParseUtil.readRangeInt(parms[3], 0, 255, 255);
|
||||
|
||||
a = 255;
|
||||
if (parms.length > 4)
|
||||
a = GuiUtil.readRangeInt(parms[4], 0, 255, 255);
|
||||
a = ParseUtil.readRangeInt(parms[4], 0, 255, 255);
|
||||
|
||||
aConfig.bgColor = new Color(r, g, b, a);
|
||||
}
|
||||
@@ -199,20 +213,20 @@ public class Banner extends JComponent
|
||||
{
|
||||
int r, g, b;
|
||||
|
||||
r = GuiUtil.readRangeInt(parms[1], 0, 255, 255);
|
||||
g = GuiUtil.readRangeInt(parms[2], 0, 255, 255);
|
||||
b = GuiUtil.readRangeInt(parms[3], 0, 255, 255);
|
||||
r = ParseUtil.readRangeInt(parms[1], 0, 255, 255);
|
||||
g = ParseUtil.readRangeInt(parms[2], 0, 255, 255);
|
||||
b = ParseUtil.readRangeInt(parms[3], 0, 255, 255);
|
||||
aConfig.borderColor = new Color(r, g, b);
|
||||
|
||||
if (parms.length > 4)
|
||||
aConfig.borderWidth = GuiUtil.readRangeInt(parms[4], 0, 10, 0);
|
||||
aConfig.borderWidth = ParseUtil.readRangeInt(parms[4], 0, 10, 0);
|
||||
|
||||
if (parms.length > 5)
|
||||
aConfig.borderPad = GuiUtil.readRangeInt(parms[5], -20, 20, 0);
|
||||
aConfig.borderPad = ParseUtil.readRangeInt(parms[5], -20, 20, 0);
|
||||
}
|
||||
else if (parms[0].equalsIgnoreCase("repeatMsg") == true && parms.length == 2)
|
||||
{
|
||||
aConfig.numRepeats = GuiUtil.readRangeInt(parms[1], -1, 100, 0);
|
||||
aConfig.numRepeats = ParseUtil.readRangeInt(parms[1], -1, 100, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component.banner;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@@ -1,26 +1,51 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component.model;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.swing.ComboBoxModel;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import glum.gui.component.GComboBox;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ComboBoxModel} that is used with {@link GComboBox}.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GComboBoxModel<G1> extends GListModel<G1> implements ComboBoxModel<G1>
|
||||
{
|
||||
protected G1 chosenItem;
|
||||
private G1 chosenItem;
|
||||
|
||||
public GComboBoxModel(G1... aItemArr)
|
||||
/**
|
||||
* Standard Constructor
|
||||
*/
|
||||
public GComboBoxModel(Collection<G1> aItemC)
|
||||
{
|
||||
this(Lists.newArrayList(aItemArr));
|
||||
}
|
||||
|
||||
public GComboBoxModel(Collection<G1> aItemList)
|
||||
{
|
||||
super(aItemList);
|
||||
super(aItemC);
|
||||
|
||||
chosenItem = null;
|
||||
if (itemList.size() > 0)
|
||||
chosenItem = itemList.get(0);
|
||||
if (itemL.size() > 0)
|
||||
chosenItem = itemL.get(0);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public GComboBoxModel(G1... aItemArr)
|
||||
{
|
||||
this(ImmutableList.copyOf(aItemArr));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,17 +63,18 @@ public class GComboBoxModel<G1> extends GListModel<G1> implements ComboBoxModel<
|
||||
super.removeItem(aItem);
|
||||
|
||||
chosenItem = null;
|
||||
if (itemList.size() > 0)
|
||||
chosenItem = itemList.get(0);
|
||||
if (itemL.size() > 0)
|
||||
chosenItem = itemL.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note aItem must be of the Generified type
|
||||
*/
|
||||
@Override @SuppressWarnings("unchecked")
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void setSelectedItem(Object aItem)
|
||||
{
|
||||
chosenItem = (G1)aItem;
|
||||
chosenItem = (G1) aItem;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,79 +1,98 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.component.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
import javax.swing.AbstractListModel;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* Generified mutable ListModel
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class GListModel<G1> extends AbstractListModel<G1>
|
||||
{
|
||||
protected List<G1> itemList;
|
||||
protected final List<G1> itemL;
|
||||
|
||||
public GListModel(Collection<G1> aItemList)
|
||||
/**
|
||||
* Standard Constructor
|
||||
*/
|
||||
public GListModel(Collection<G1> aItemC)
|
||||
{
|
||||
itemList = Lists.newArrayList(aItemList);
|
||||
itemL = new ArrayList<>(aItemC);
|
||||
}
|
||||
|
||||
// public GListModel(G1... aItemArr)
|
||||
// {
|
||||
// itemList = Lists.newArrayList(aItemArr);
|
||||
// }
|
||||
//
|
||||
/**
|
||||
* Adds aItem to this model
|
||||
*/
|
||||
public void addItem(G1 aItem)
|
||||
{
|
||||
int index;
|
||||
|
||||
itemList.add(aItem);
|
||||
|
||||
index = itemList.size() - 1;
|
||||
itemL.add(aItem);
|
||||
|
||||
var index = itemL.size() - 1;
|
||||
fireIntervalAdded(this, index, index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes aItem from this model
|
||||
*/
|
||||
public void removeItem(G1 aItem)
|
||||
{
|
||||
int index;
|
||||
|
||||
index = itemList.indexOf(aItem);
|
||||
itemList.remove(aItem);
|
||||
|
||||
var index = itemL.indexOf(aItem);
|
||||
itemL.remove(aItem);
|
||||
|
||||
fireIntervalRemoved(this, index, index);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all the items from this model
|
||||
*/
|
||||
public void removeAllItems()
|
||||
{
|
||||
int lastIndex;
|
||||
|
||||
// Bail if the list is empty
|
||||
if (itemList.isEmpty() == true)
|
||||
if (itemL.isEmpty() == true)
|
||||
return;
|
||||
|
||||
lastIndex = itemList.size() - 1;
|
||||
itemList.clear();
|
||||
|
||||
|
||||
var lastIndex = itemL.size() - 1;
|
||||
itemL.clear();
|
||||
|
||||
fireIntervalRemoved(this, 0, lastIndex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Replaces the original item with the provided replacement.
|
||||
* <p>
|
||||
* Throws an exception if the original item is not installed.
|
||||
*/
|
||||
public void replaceItem(G1 aOrigItem, G1 aReplItem)
|
||||
{
|
||||
int tmpIdx = itemL.indexOf(aOrigItem);
|
||||
if (tmpIdx == -1)
|
||||
throw new RuntimeException("The original item is not in the list");
|
||||
|
||||
itemL.set(tmpIdx, aReplItem);
|
||||
|
||||
fireContentsChanged(this, tmpIdx, tmpIdx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a list of all the items
|
||||
*/
|
||||
public ArrayList<G1> getAllItems()
|
||||
public List<G1> getAllItems()
|
||||
{
|
||||
return Lists.newArrayList(itemList);
|
||||
return new ArrayList<>(itemL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,18 +100,18 @@ public class GListModel<G1> extends AbstractListModel<G1>
|
||||
*/
|
||||
public int indexOf(G1 aItem)
|
||||
{
|
||||
return itemList.indexOf(aItem);
|
||||
return itemL.indexOf(aItem);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize()
|
||||
{
|
||||
return itemList.size();
|
||||
return itemL.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public G1 getElementAt(int index)
|
||||
{
|
||||
return itemList.get(index);
|
||||
return itemL.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dnd;
|
||||
|
||||
import java.awt.datatransfer.Transferable;
|
||||
@@ -6,19 +19,20 @@ import javax.swing.JComponent;
|
||||
import javax.swing.TransferHandler;
|
||||
|
||||
/**
|
||||
* Generic TransferHandler that supports transferring an arbitrary Transferable. Note that before the DnD transfer
|
||||
* mechanism is triggered via the method exportAsDrag(), the developer must set in the Transferable via the method
|
||||
* setWorkTransferable().
|
||||
* Generic {@link TransferHandler} that supports transferring an arbitrary {@link Transferable}. Note that before the
|
||||
* DnD transfer mechanism is triggered via the method exportAsDrag(), the developer must set in the {@link Transferable}
|
||||
* via the method {@link #setWorkTransferable(Transferable)}.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class PlainTransferHandler extends TransferHandler
|
||||
{
|
||||
// State vars
|
||||
protected Transferable workTransferable;
|
||||
|
||||
/** Standard Constructor */
|
||||
public PlainTransferHandler()
|
||||
{
|
||||
super();
|
||||
|
||||
workTransferable = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import javax.swing.Icon;
|
||||
@@ -11,18 +24,16 @@ public class BaseDockable extends DefaultDockable
|
||||
// Tells whether this Dockable can be dragged and dropped to another station
|
||||
private DockStation homeStation;
|
||||
private boolean isTransferable;
|
||||
|
||||
|
||||
public BaseDockable()
|
||||
{
|
||||
super();
|
||||
|
||||
isTransferable = true;
|
||||
}
|
||||
|
||||
|
||||
public BaseDockable(JComponent aComp, String aTitle, Icon aIcon)
|
||||
{
|
||||
super(aComp, aTitle, aIcon);
|
||||
|
||||
|
||||
isTransferable = true;
|
||||
}
|
||||
|
||||
@@ -30,21 +41,19 @@ public class BaseDockable extends DefaultDockable
|
||||
{
|
||||
if (isTransferable == true)
|
||||
return true;
|
||||
|
||||
|
||||
// We can only be transfered to our homeStation when we are not transferable
|
||||
return aStation == homeStation;
|
||||
}
|
||||
|
||||
|
||||
public void setTransferable(boolean aBool)
|
||||
{
|
||||
homeStation = null;
|
||||
isTransferable = aBool;
|
||||
|
||||
|
||||
|
||||
// Record our parent when we become non transferable
|
||||
if (isTransferable == false)
|
||||
homeStation = getDockParent();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import glum.gui.dock.action.Closeable;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import bibliothek.gui.DockStation;
|
||||
|
||||
@@ -1,14 +1,26 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import bibliothek.gui.DockController;
|
||||
import bibliothek.gui.DockFrontend;
|
||||
import bibliothek.gui.DockStation;
|
||||
@@ -20,6 +32,11 @@ import bibliothek.gui.dock.action.actions.SimpleButtonAction;
|
||||
import bibliothek.gui.dock.station.screen.ScreenFullscreenAction;
|
||||
import bibliothek.gui.dock.station.split.SplitFullScreenAction;
|
||||
|
||||
/**
|
||||
* Collection of utility methods useful for working dockables / dock stations.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class DockUtil
|
||||
{
|
||||
/**
|
||||
@@ -27,14 +44,14 @@ public class DockUtil
|
||||
*/
|
||||
public static SimpleButtonAction createAction(String aText, Icon aIcon, ActionListener aListener)
|
||||
{
|
||||
SimpleButtonAction aAction;
|
||||
SimpleButtonAction retAction;
|
||||
|
||||
aAction = new SimpleButtonAction();
|
||||
aAction.setText(aText);
|
||||
aAction.setIcon(aIcon);
|
||||
aAction.addActionListener(aListener);
|
||||
retAction = new SimpleButtonAction();
|
||||
retAction.setText(aText);
|
||||
retAction.setIcon(aIcon);
|
||||
retAction.addActionListener(aListener);
|
||||
|
||||
return aAction;
|
||||
return retAction;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,24 +61,24 @@ public class DockUtil
|
||||
*/
|
||||
public static DockAction createFullScreenAction(DockStation aStation, DockController aController)
|
||||
{
|
||||
DockAction fullScreenAction;
|
||||
DockAction retAction;
|
||||
|
||||
if (aStation instanceof SplitDockStation)
|
||||
{
|
||||
fullScreenAction = new SplitFullScreenAction((SplitDockStation)aStation);
|
||||
((SplitFullScreenAction)fullScreenAction).setController(aController);
|
||||
retAction = new SplitFullScreenAction((SplitDockStation) aStation);
|
||||
((SplitFullScreenAction) retAction).setController(aController);
|
||||
}
|
||||
else if (aStation instanceof ScreenDockStation)
|
||||
{
|
||||
fullScreenAction = new ScreenFullscreenAction((ScreenDockStation)aStation);
|
||||
((ScreenFullscreenAction)fullScreenAction).setController(aController);
|
||||
retAction = new ScreenFullscreenAction((ScreenDockStation) aStation);
|
||||
((ScreenFullscreenAction) retAction).setController(aController);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Unsupported Dockable type: " + aStation);
|
||||
}
|
||||
|
||||
return fullScreenAction;
|
||||
return retAction;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,7 +92,7 @@ public class DockUtil
|
||||
{
|
||||
evalDockable = aStation.getDockable(c1);
|
||||
if (evalDockable instanceof DockStation)
|
||||
evalDockable = findDockable((DockStation)evalDockable, aClass);
|
||||
evalDockable = findDockable((DockStation) evalDockable, aClass);
|
||||
|
||||
if (evalDockable.getClass() == aClass)
|
||||
return aClass.cast(evalDockable);
|
||||
@@ -90,19 +107,19 @@ public class DockUtil
|
||||
*/
|
||||
public static List<Dockable> findDockableList(DockFrontend aFrontend, Class<?>... aClassArr)
|
||||
{
|
||||
Set<Class<?>> classSet;
|
||||
List<Dockable> itemList;
|
||||
Set<Class<?>> tmpClassS;
|
||||
List<Dockable> retItemL;
|
||||
|
||||
// Transform the match class array to a set
|
||||
classSet = Sets.newHashSet();
|
||||
tmpClassS = new HashSet<>();
|
||||
for (Class<?> aClass : aClassArr)
|
||||
classSet.add(aClass);
|
||||
tmpClassS.add(aClass);
|
||||
|
||||
itemList = Lists.newLinkedList();
|
||||
retItemL = new ArrayList<>();
|
||||
for (DockStation aStation : aFrontend.getRoots())
|
||||
findDockableList(aStation, classSet, itemList);
|
||||
findDockableList(aStation, tmpClassS, retItemL);
|
||||
|
||||
return itemList;
|
||||
return retItemL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,18 +128,18 @@ public class DockUtil
|
||||
*/
|
||||
public static <G1 extends Dockable> List<G1> findDockableList(DockFrontend aFrontend, Class<G1> aClass)
|
||||
{
|
||||
Set<Class<?>> classSet;
|
||||
List<G1> itemList;
|
||||
Set<Class<?>> tmpClassS;
|
||||
List<G1> retItemL;
|
||||
|
||||
// Transform the match class array to a set
|
||||
classSet = Sets.newHashSet();
|
||||
classSet.add(aClass);
|
||||
tmpClassS = new HashSet<>();
|
||||
tmpClassS.add(aClass);
|
||||
|
||||
itemList = Lists.newLinkedList();
|
||||
retItemL = new ArrayList<>();
|
||||
for (DockStation aStation : aFrontend.getRoots())
|
||||
findDockableList(aStation, classSet, itemList);
|
||||
findDockableList(aStation, tmpClassS, retItemL);
|
||||
|
||||
return itemList;
|
||||
return retItemL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,18 +148,18 @@ public class DockUtil
|
||||
*/
|
||||
public static List<Dockable> findDockableList(DockStation aStation, Class<?>... aClassArr)
|
||||
{
|
||||
Set<Class<?>> classSet;
|
||||
List<Dockable> itemList;
|
||||
Set<Class<?>> tmpClassS;
|
||||
List<Dockable> retItemL;
|
||||
|
||||
// Transform the match class array to a set
|
||||
classSet = Sets.newHashSet();
|
||||
tmpClassS = new HashSet<>();
|
||||
for (Class<?> aClass : aClassArr)
|
||||
classSet.add(aClass);
|
||||
tmpClassS.add(aClass);
|
||||
|
||||
itemList = Lists.newLinkedList();
|
||||
findDockableList(aStation, classSet, itemList);
|
||||
retItemL = new ArrayList<>();
|
||||
findDockableList(aStation, tmpClassS, retItemL);
|
||||
|
||||
return itemList;
|
||||
return retItemL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,32 +168,32 @@ public class DockUtil
|
||||
*/
|
||||
public static <G1 extends Dockable> List<G1> findDockableList(DockStation aStation, Class<G1> aClass)
|
||||
{
|
||||
Set<Class<?>> classSet;
|
||||
List<G1> itemList;
|
||||
Set<Class<?>> tmpClassS;
|
||||
List<G1> retItemL;
|
||||
|
||||
// Transform the match class array to a set
|
||||
classSet = Sets.newHashSet();
|
||||
classSet.add(aClass);
|
||||
tmpClassS = new HashSet<>();
|
||||
tmpClassS.add(aClass);
|
||||
|
||||
itemList = Lists.newLinkedList();
|
||||
findDockableList(aStation, classSet, itemList);
|
||||
retItemL = new ArrayList<>();
|
||||
findDockableList(aStation, tmpClassS, retItemL);
|
||||
|
||||
return itemList;
|
||||
return retItemL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to remove all PlotGroupStations and ChartDockables
|
||||
*/
|
||||
public static <G1 extends Dockable> void removeAllDockablesOfType(DockFrontend aFrontend, Class<?>... dockTypeArr)
|
||||
public static <G1 extends Dockable> void removeAllDockablesOfType(DockFrontend aFrontend, Class<?>... aDockTypeArr)
|
||||
{
|
||||
List<Dockable> dockList;
|
||||
List<Dockable> dockL;
|
||||
DockStation dockStation;
|
||||
|
||||
// Gather all of the Dockables of interest
|
||||
dockList = DockUtil.findDockableList(aFrontend, dockTypeArr);
|
||||
dockL = DockUtil.findDockableList(aFrontend, aDockTypeArr);
|
||||
|
||||
// Remove all of the Dockables
|
||||
for (Dockable aDock : dockList)
|
||||
for (Dockable aDock : dockL)
|
||||
{
|
||||
dockStation = aDock.getDockParent();
|
||||
if (dockStation != null)
|
||||
@@ -189,24 +206,25 @@ public class DockUtil
|
||||
* results will be stored in aItemList
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <G1 extends Dockable> void findDockableList(DockStation aStation, Set<Class<?>> aClassSet, List<G1> aItemList)
|
||||
private static <G1 extends Dockable> void findDockableList(DockStation aStation, Set<Class<?>> aClassS,
|
||||
List<G1> aItemL)
|
||||
{
|
||||
Dockable evalDockable;
|
||||
|
||||
for (int c1 = 0; c1 < aStation.getDockableCount(); c1++)
|
||||
{
|
||||
evalDockable = aStation.getDockable(c1);
|
||||
for (Class<?> aClass : aClassSet)
|
||||
for (Class<?> aClass : aClassS)
|
||||
{
|
||||
if (aClass.isAssignableFrom(evalDockable.getClass()) == true)
|
||||
{
|
||||
aItemList.add((G1)evalDockable);
|
||||
aItemL.add((G1) evalDockable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (evalDockable instanceof DockStation)
|
||||
findDockableList((DockStation)evalDockable, aClassSet, aItemList);
|
||||
findDockableList((DockStation) evalDockable, aClassS, aItemL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,38 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
import bibliothek.gui.DockFrontend;
|
||||
import glum.gui.panel.generic.BaseTextInputPanel;
|
||||
|
||||
import glum.gui.panel.generic.TextInputPanel;
|
||||
|
||||
public class FrontendAddConfigPanel extends TextInputPanel
|
||||
/**
|
||||
* UI component that allows the creation of a docking configuration.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class FrontendAddConfigPanel extends BaseTextInputPanel
|
||||
{
|
||||
// Constants
|
||||
public static final String DEFAULT_NAME = "Default";
|
||||
|
||||
// State vars
|
||||
protected DockFrontend refFrontend;
|
||||
// Ref vars
|
||||
private final DockFrontend refFrontend;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
/** Standard Constructor */
|
||||
public FrontendAddConfigPanel(Component aParent, DockFrontend aFrontend)
|
||||
{
|
||||
super(aParent);
|
||||
@@ -32,14 +47,11 @@ public class FrontendAddConfigPanel extends TextInputPanel
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Object source;
|
||||
String configName;
|
||||
|
||||
// Save of the configuration
|
||||
source = e.getSource();
|
||||
var source = e.getSource();
|
||||
if (source == acceptB)
|
||||
{
|
||||
configName = getInput();
|
||||
var configName = getInput();
|
||||
refFrontend.save(configName);
|
||||
}
|
||||
|
||||
@@ -50,16 +62,14 @@ public class FrontendAddConfigPanel extends TextInputPanel
|
||||
@Override
|
||||
protected void updateGui()
|
||||
{
|
||||
String inputStr, infoMsg;
|
||||
boolean isEnabled;
|
||||
|
||||
// Assume the GUI is invalid
|
||||
isEnabled = false;
|
||||
var isEnabled = false;
|
||||
|
||||
// Retrieve the name
|
||||
inputStr = inputTF.getText();
|
||||
var inputStr = inputTF.getText();
|
||||
|
||||
// Determine the validity of specified name
|
||||
String infoMsg;
|
||||
if (inputStr.equals("") == true)
|
||||
{
|
||||
infoMsg = "Please enter a valid configuration name.";
|
||||
|
||||
@@ -1,21 +1,29 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Collection;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.border.BevelBorder;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
|
||||
//import echo.gui.LookUp;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import bibliothek.gui.DockFrontend;
|
||||
import glum.database.QueryItem;
|
||||
import glum.gui.FocusUtil;
|
||||
import glum.gui.GuiUtil;
|
||||
@@ -25,24 +33,27 @@ import glum.gui.panel.itemList.ItemListPanel;
|
||||
import glum.gui.panel.itemList.StaticItemProcessor;
|
||||
import glum.gui.panel.itemList.query.QueryComposer;
|
||||
import glum.gui.panel.itemList.query.QueryItemHandler;
|
||||
|
||||
import bibliothek.gui.DockFrontend;
|
||||
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* UI component that provides a listing of all docking configurations.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class FrontendManageConfigPanel extends GlassPanel implements ActionListener, ListSelectionListener
|
||||
{
|
||||
// GUI vars
|
||||
protected ItemListPanel<ConfigItem> listPanel;
|
||||
protected JButton deleteB, closeB;
|
||||
private ItemListPanel<ConfigItem, LookUp> listPanel;
|
||||
private JButton deleteB, closeB;
|
||||
|
||||
// State vars
|
||||
protected DockFrontend refFrontend;
|
||||
protected StaticItemProcessor<ConfigItem> myItemProcessor;
|
||||
private DockFrontend refFrontend;
|
||||
private StaticItemProcessor<ConfigItem> myItemProcessor;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param aFrontend
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aFrontend
|
||||
*/
|
||||
public FrontendManageConfigPanel(Component aParent, DockFrontend aFrontend)
|
||||
{
|
||||
@@ -53,8 +64,8 @@ public class FrontendManageConfigPanel extends GlassPanel implements ActionListe
|
||||
|
||||
// Build the actual GUI
|
||||
buildGuiArea();
|
||||
setPreferredSize(new Dimension(250, 300));//TODO:getPreferredSize().height));
|
||||
|
||||
setPreferredSize(new Dimension(250, 300));// TODO:getPreferredSize().height));
|
||||
|
||||
// Set up keyboard short cuts
|
||||
FocusUtil.addAncestorKeyBinding(this, "ESCAPE", new ClickAction(closeB));
|
||||
FocusUtil.addAncestorKeyBinding(this, "ENTER", new ClickAction(closeB));
|
||||
@@ -65,19 +76,16 @@ public class FrontendManageConfigPanel extends GlassPanel implements ActionListe
|
||||
public void setVisible(boolean aBool)
|
||||
{
|
||||
resetGui();
|
||||
|
||||
|
||||
super.setVisible(aBool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
public void actionPerformed(ActionEvent aEvent)
|
||||
{
|
||||
Object source;
|
||||
ConfigItem chosenItem;
|
||||
var chosenItem = listPanel.getSelectedItem();
|
||||
|
||||
chosenItem = listPanel.getSelectedItem();
|
||||
|
||||
source = e.getSource();
|
||||
var source = aEvent.getSource();
|
||||
if (source == deleteB)
|
||||
{
|
||||
refFrontend.delete(chosenItem.getName());
|
||||
@@ -94,7 +102,7 @@ public class FrontendManageConfigPanel extends GlassPanel implements ActionListe
|
||||
{
|
||||
if (aEvent.getValueIsAdjusting() == true)
|
||||
return;
|
||||
|
||||
|
||||
updateGui();
|
||||
}
|
||||
|
||||
@@ -103,34 +111,27 @@ public class FrontendManageConfigPanel extends GlassPanel implements ActionListe
|
||||
*/
|
||||
private void buildGuiArea()
|
||||
{
|
||||
JLabel tmpL;
|
||||
QueryItemHandler<ConfigItem> aItemHandler;
|
||||
QueryComposer<LookUp> aComposer;
|
||||
|
||||
|
||||
setLayout(new MigLayout("", "[grow][][]", "[][grow][]"));
|
||||
|
||||
tmpL = new JLabel("Select configuration:", JLabel.CENTER);
|
||||
add(tmpL, "growx,span 4,wrap");
|
||||
|
||||
// Construct the actual table panel
|
||||
aComposer = new QueryComposer<LookUp>();
|
||||
aComposer.addAttribute(LookUp.Name, String.class, "Configuration", null);
|
||||
|
||||
myItemProcessor = new StaticItemProcessor<ConfigItem>();
|
||||
aItemHandler = new QueryItemHandler<ConfigItem>(aComposer);
|
||||
listPanel = new ItemListPanel<ConfigItem>(aItemHandler, myItemProcessor, false, true);
|
||||
var tmpL = new JLabel("Select configuration:", JLabel.CENTER);
|
||||
add(tmpL, "growx,span 4,wrap");
|
||||
|
||||
// Construct the actual table panel
|
||||
var tmpComposer = new QueryComposer<LookUp>();
|
||||
tmpComposer.addAttribute(LookUp.Name, String.class, "Configuration", null);
|
||||
|
||||
myItemProcessor = new StaticItemProcessor<>();
|
||||
var tmpIH = new QueryItemHandler<ConfigItem, LookUp>();
|
||||
listPanel = new ItemListPanel<>(tmpIH, myItemProcessor, tmpComposer, true);
|
||||
listPanel.addListSelectionListener(this);
|
||||
add(listPanel, "growx,growy,span 4,wrap");
|
||||
|
||||
|
||||
// Control area
|
||||
deleteB = GuiUtil.createJButton("Delete", this);
|
||||
closeB = GuiUtil.createJButton("Close", this);
|
||||
|
||||
add(deleteB, "skip 1,span 1");
|
||||
add(closeB, "span 1");
|
||||
|
||||
setBorder(new BevelBorder(BevelBorder.RAISED));
|
||||
add(deleteB, "skip 1");
|
||||
add(closeB, "");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -138,31 +139,19 @@ public class FrontendManageConfigPanel extends GlassPanel implements ActionListe
|
||||
*/
|
||||
private void resetGui()
|
||||
{
|
||||
Collection<String> strList;
|
||||
Collection<ConfigItem> itemList;
|
||||
|
||||
itemList = Lists.newLinkedList();
|
||||
|
||||
strList = refFrontend.getSettings();
|
||||
for (String aStr : strList)
|
||||
var itemL = new ArrayList<ConfigItem>();
|
||||
var strL = refFrontend.getSettings();
|
||||
for (String aStr : strL)
|
||||
{
|
||||
// Add only non reserved items
|
||||
if (aStr.charAt(0) != '.')
|
||||
itemList.add(new ConfigItem(aStr));
|
||||
itemL.add(new ConfigItem(aStr));
|
||||
}
|
||||
|
||||
myItemProcessor.setItems(itemList);
|
||||
|
||||
// TODO: Ugly code: Should be able to just call updateGui but can not
|
||||
SwingUtilities.invokeLater(new Runnable()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
updateGui();
|
||||
}
|
||||
});
|
||||
|
||||
myItemProcessor.setItems(itemL);
|
||||
|
||||
// TODO: Should be able to just call updateGui but can not
|
||||
SwingUtilities.invokeLater(() -> updateGui());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,58 +159,46 @@ public class FrontendManageConfigPanel extends GlassPanel implements ActionListe
|
||||
*/
|
||||
private void updateGui()
|
||||
{
|
||||
ConfigItem chosenItem;
|
||||
boolean isEnabled;
|
||||
|
||||
chosenItem = listPanel.getSelectedItem();
|
||||
|
||||
var chosenItem = listPanel.getSelectedItem();
|
||||
if (chosenItem != null)
|
||||
refFrontend.load(chosenItem.getName());
|
||||
|
||||
isEnabled = chosenItem != null;
|
||||
|
||||
var isEnabled = chosenItem != null;
|
||||
deleteB.setEnabled(isEnabled);
|
||||
|
||||
|
||||
// Ensure we have the focus.
|
||||
//listPanel.requestFocusInWindow();
|
||||
//listPanel.requestFocusInWindow();
|
||||
repaint();
|
||||
|
||||
// TODO: Ugly code: Not sure why need to request focus multiple times to ensure we regrab
|
||||
// TODO: Ugly code: Not sure why need to request focus multiple times to ensure we regrab
|
||||
// the focus. This is particularly true when there are multiple DockStations located on different
|
||||
// windows
|
||||
SwingUtilities.invokeLater(new Runnable()
|
||||
{
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
listPanel.getTable().requestFocus();
|
||||
|
||||
SwingUtilities.invokeLater(new Runnable()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
listPanel.getTable().requestFocus();
|
||||
}
|
||||
});
|
||||
|
||||
// listPanel.getTable().getFocusCycleRootAncestor().setFocusCycleRoot(true);
|
||||
|
||||
SwingUtilities.invokeLater(() -> listPanel.getTable().requestFocus());
|
||||
|
||||
// listPanel.getTable().getFocusCycleRootAncestor().setFocusCycleRoot(true);
|
||||
listPanel.getTable().requestFocusInWindow();
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Internal class only used to wrap named (string) settings into
|
||||
* a QueryItem
|
||||
* Internal class only used to wrap named (string) settings into a QueryItem.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
class ConfigItem implements QueryItem<LookUp>
|
||||
{
|
||||
private String refName;
|
||||
|
||||
// Attributes
|
||||
private final String refName;
|
||||
|
||||
public ConfigItem(String aName)
|
||||
{
|
||||
refName = aName;
|
||||
@@ -246,7 +223,7 @@ public class FrontendManageConfigPanel extends GlassPanel implements ActionListe
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
public enum LookUp
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import bibliothek.gui.DockStation;
|
||||
import bibliothek.gui.dock.DockElement;
|
||||
import bibliothek.gui.dock.layout.DockSituationIgnore;
|
||||
@@ -12,50 +24,52 @@ import bibliothek.gui.dock.perspective.PerspectiveStation;
|
||||
|
||||
public class PlainDockSituationIgnore implements DockSituationIgnore
|
||||
{
|
||||
private Set<Class<?>> ignoreClassSet;
|
||||
|
||||
// State vars
|
||||
private Set<Class<?>> ignoreClassS;
|
||||
|
||||
/** Standard Constructor */
|
||||
public PlainDockSituationIgnore()
|
||||
{
|
||||
ignoreClassSet = Sets.newLinkedHashSet();
|
||||
ignoreClassS = new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Method to register a new type of Dockable/Station to ignore
|
||||
*/
|
||||
public void addIgnoreClass(Class<?> aClass)
|
||||
{
|
||||
ignoreClassSet.add(aClass);
|
||||
ignoreClassS.add(aClass);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean ignoreElement(PerspectiveElement aElement)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean ignoreElement(DockElement aElement)
|
||||
{
|
||||
// Check to see if aElement is of one of the types in ignoreClassSet
|
||||
for (Class<?> aClass : ignoreClassSet)
|
||||
for (var aClass : ignoreClassS)
|
||||
{
|
||||
if (aClass.isAssignableFrom(aElement.getClass()) == true)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean ignoreChildren(PerspectiveStation station)
|
||||
public boolean ignoreChildren(PerspectiveStation aStation)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean ignoreChildren(DockStation station)
|
||||
public boolean ignoreChildren(DockStation aStation)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
|
||||
@@ -1,211 +1,196 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import glum.io.IoUtil;
|
||||
|
||||
/**
|
||||
* Container which holds a mapping of keys (String) to a bunch of primitive objects.
|
||||
* <p>
|
||||
* Serialization of content is supported via {@link #readBin(DataInputStream)} and {@link #writeBin(DataOutputStream)}
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class PrimConfig
|
||||
{
|
||||
// Constants
|
||||
public static final byte CODE_BOOL = 1;
|
||||
public static final byte CODE_INT = 10;
|
||||
public static final byte CODE_LONG = 11;
|
||||
public static final byte CODE_SHORT = 12;
|
||||
public static final byte CODE_FLOAT = 13;
|
||||
public static final byte CODE_BOOL = 1;
|
||||
public static final byte CODE_INT = 10;
|
||||
public static final byte CODE_LONG = 11;
|
||||
public static final byte CODE_SHORT = 12;
|
||||
public static final byte CODE_FLOAT = 13;
|
||||
public static final byte CODE_DOUBLE = 14;
|
||||
public static final byte CODE_STRING = 20;
|
||||
|
||||
// State vars
|
||||
protected Map<String, Object> mySingletonMap;
|
||||
|
||||
/**
|
||||
* Container which holds a mapping of keys (String) to a bunch
|
||||
* of primitive objects.
|
||||
*/
|
||||
protected Map<String, Object> mySingletonM;
|
||||
|
||||
/** Standard Constructor */
|
||||
public PrimConfig()
|
||||
{
|
||||
mySingletonMap = Maps.newLinkedHashMap();
|
||||
mySingletonM = new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the boolean associated with aKey
|
||||
* If no such value is found then defaultVal is returned.
|
||||
* Returns the boolean associated with aKey If no such value is found then defaultVal is returned.
|
||||
*/
|
||||
public boolean getBoolean(String aKey, boolean defaultVal)
|
||||
public boolean getBoolean(String aKey, boolean aDefaultVal)
|
||||
{
|
||||
Object aValue;
|
||||
|
||||
// If no value associated with the key then return defaultVal
|
||||
aValue = mySingletonMap.get(aKey);
|
||||
if (aValue == null || aValue.getClass() != Boolean.class)
|
||||
return defaultVal;
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal == null || tmpVal.getClass() != Boolean.class)
|
||||
return aDefaultVal;
|
||||
|
||||
return (Boolean)aValue;
|
||||
return (Boolean) tmpVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the int associated with aKey
|
||||
* If no such value is found then defaultVal is returned.
|
||||
* Returns the int associated with aKey If no such value is found then defaultVal is returned.
|
||||
*/
|
||||
public int getInt(String aKey, int defaultVal)
|
||||
public int getInt(String aKey, int aDefaultVal)
|
||||
{
|
||||
Object aValue;
|
||||
|
||||
// If no value associated with the key then return defaultVal
|
||||
aValue = mySingletonMap.get(aKey);
|
||||
if (aValue == null || aValue.getClass() != Integer.class)
|
||||
return defaultVal;
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal == null || tmpVal.getClass() != Integer.class)
|
||||
return aDefaultVal;
|
||||
|
||||
return (Integer)aValue;
|
||||
return (Integer) tmpVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the long associated with aKey
|
||||
* If no such value is found then defaultVal is returned.
|
||||
* Returns the long associated with aKey If no such value is found then defaultVal is returned.
|
||||
*/
|
||||
public long getLong(String aKey, long defaultVal)
|
||||
public long getLong(String aKey, long aDefaultVal)
|
||||
{
|
||||
Object aValue;
|
||||
|
||||
// If no value associated with the key then return defaultVal
|
||||
aValue = mySingletonMap.get(aKey);
|
||||
if (aValue == null || aValue.getClass() != Long.class)
|
||||
return defaultVal;
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal == null || tmpVal.getClass() != Long.class)
|
||||
return aDefaultVal;
|
||||
|
||||
return (Long)aValue;
|
||||
return (Long) tmpVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the short associated with aKey
|
||||
* If no such value is found then defaultVal is returned.
|
||||
* Returns the short associated with aKey If no such value is found then defaultVal is returned.
|
||||
*/
|
||||
public short getShort(String aKey, short defaultVal)
|
||||
public short getShort(String aKey, short aDefaultVal)
|
||||
{
|
||||
Object aValue;
|
||||
|
||||
// If no value associated with the key then return defaultVal
|
||||
aValue = mySingletonMap.get(aKey);
|
||||
if (aValue == null || aValue.getClass() != Short.class)
|
||||
return defaultVal;
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal == null || tmpVal.getClass() != Short.class)
|
||||
return aDefaultVal;
|
||||
|
||||
return (Short)aValue;
|
||||
return (Short) tmpVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the float associated with aKey
|
||||
* If no such value is found then defaultVal is returned.
|
||||
* Returns the float associated with aKey If no such value is found then defaultVal is returned.
|
||||
*/
|
||||
public float getFloat(String aKey, float defaultVal)
|
||||
public float getFloat(String aKey, float aDefaultVal)
|
||||
{
|
||||
Object aValue;
|
||||
|
||||
// If no value associated with the key then return defaultVal
|
||||
aValue = mySingletonMap.get(aKey);
|
||||
if (aValue == null || aValue.getClass() != Float.class)
|
||||
return defaultVal;
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal == null || tmpVal.getClass() != Float.class)
|
||||
return aDefaultVal;
|
||||
|
||||
return (Float)aValue;
|
||||
return (Float) tmpVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the double associated with aKey
|
||||
* If no such value is found then defaultVal is returned.
|
||||
* Returns the double associated with aKey If no such value is found then defaultVal is returned.
|
||||
*/
|
||||
public double getDouble(String aKey, double defaultVal)
|
||||
public double getDouble(String aKey, double aDefaultVal)
|
||||
{
|
||||
Object aValue;
|
||||
|
||||
// If no value associated with the key then return defaultVal
|
||||
aValue = mySingletonMap.get(aKey);
|
||||
if (aValue == null || aValue.getClass() != Double.class)
|
||||
return defaultVal;
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal == null || tmpVal.getClass() != Double.class)
|
||||
return aDefaultVal;
|
||||
|
||||
return (Double)aValue;
|
||||
return (Double) tmpVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the String associated with aKey
|
||||
* If no such value is found then defaultVal is returned.
|
||||
* Returns the String associated with aKey If no such value is found then defaultVal is returned.
|
||||
*/
|
||||
public String getString(String aKey, String defaultVal)
|
||||
public String getString(String aKey, String aDefaultVal)
|
||||
{
|
||||
Object aValue;
|
||||
|
||||
// If no value associated with the key then return defaultVal
|
||||
aValue = mySingletonMap.get(aKey);
|
||||
if (aValue == null || aValue.getClass() != String.class)
|
||||
return defaultVal;
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal == null || tmpVal.getClass() != String.class)
|
||||
return aDefaultVal;
|
||||
|
||||
return (String)aValue;
|
||||
return (String) tmpVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates aVal with aKey. Note this will overwrite any
|
||||
* previous association.
|
||||
* Associates aVal with aKey. Note this will overwrite any previous association.
|
||||
*/
|
||||
public void setBoolean(String aKey, boolean aValue)
|
||||
{
|
||||
mySingletonMap.put(aKey, aValue);
|
||||
mySingletonM.put(aKey, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates aVal with aKey. Note this will overwrite any
|
||||
* previous association.
|
||||
* Associates aVal with aKey. Note this will overwrite any previous association.
|
||||
*/
|
||||
public void setInt(String aKey, int aValue)
|
||||
{
|
||||
mySingletonMap.put(aKey, aValue);
|
||||
mySingletonM.put(aKey, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates aVal with aKey. Note this will overwrite any
|
||||
* previous association.
|
||||
* Associates aVal with aKey. Note this will overwrite any previous association.
|
||||
*/
|
||||
public void setLong(String aKey, long aValue)
|
||||
{
|
||||
mySingletonMap.put(aKey, aValue);
|
||||
mySingletonM.put(aKey, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates aVal with aKey. Note this will overwrite any
|
||||
* previous association.
|
||||
* Associates aVal with aKey. Note this will overwrite any previous association.
|
||||
*/
|
||||
public void setShort(String aKey, short aValue)
|
||||
{
|
||||
mySingletonMap.put(aKey, aValue);
|
||||
mySingletonM.put(aKey, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates aVal with aKey. Note this will overwrite any
|
||||
* previous association.
|
||||
* Associates aVal with aKey. Note this will overwrite any previous association.
|
||||
*/
|
||||
public void setFloat(String aKey, float aValue)
|
||||
{
|
||||
mySingletonMap.put(aKey, aValue);
|
||||
mySingletonM.put(aKey, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates aVal with aKey. Note this will overwrite any
|
||||
* previous association.
|
||||
* Associates aVal with aKey. Note this will overwrite any previous association.
|
||||
*/
|
||||
public void setDouble(String aKey, double aValue)
|
||||
{
|
||||
mySingletonMap.put(aKey, aValue);
|
||||
mySingletonM.put(aKey, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates aVal with aKey. Note this will overwrite any
|
||||
* previous association.
|
||||
* Associates aVal with aKey. Note this will overwrite any previous association.
|
||||
*/
|
||||
public void setString(String aKey, String aValue)
|
||||
{
|
||||
mySingletonMap.put(aKey, aValue);
|
||||
mySingletonM.put(aKey, aValue);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -213,50 +198,46 @@ public class PrimConfig
|
||||
*/
|
||||
public void readBin(DataInputStream aStream) throws IOException
|
||||
{
|
||||
int numItems;
|
||||
String aKey;
|
||||
byte aType;
|
||||
mySingletonM.clear();
|
||||
|
||||
mySingletonMap.clear();
|
||||
|
||||
numItems = aStream.readInt();
|
||||
var numItems = aStream.readInt();
|
||||
for (int c1 = 0; c1 < numItems; c1++)
|
||||
{
|
||||
aKey = IoUtil.readString(aStream);
|
||||
aType = aStream.readByte();
|
||||
|
||||
switch(aType)
|
||||
var tmpKey = IoUtil.readString(aStream);
|
||||
var tmpType = aStream.readByte();
|
||||
|
||||
switch (tmpType)
|
||||
{
|
||||
case CODE_BOOL:
|
||||
mySingletonMap.put(aKey, aStream.readBoolean());
|
||||
mySingletonM.put(tmpKey, aStream.readBoolean());
|
||||
break;
|
||||
|
||||
|
||||
case CODE_INT:
|
||||
mySingletonMap.put(aKey, aStream.readInt());
|
||||
mySingletonM.put(tmpKey, aStream.readInt());
|
||||
break;
|
||||
|
||||
|
||||
case CODE_LONG:
|
||||
mySingletonMap.put(aKey, aStream.readLong());
|
||||
mySingletonM.put(tmpKey, aStream.readLong());
|
||||
break;
|
||||
|
||||
|
||||
case CODE_SHORT:
|
||||
mySingletonMap.put(aKey, aStream.readShort());
|
||||
mySingletonM.put(tmpKey, aStream.readShort());
|
||||
break;
|
||||
|
||||
|
||||
case CODE_FLOAT:
|
||||
mySingletonMap.put(aKey, aStream.readFloat());
|
||||
mySingletonM.put(tmpKey, aStream.readFloat());
|
||||
break;
|
||||
|
||||
|
||||
case CODE_DOUBLE:
|
||||
mySingletonMap.put(aKey, aStream.readDouble());
|
||||
mySingletonM.put(tmpKey, aStream.readDouble());
|
||||
break;
|
||||
|
||||
|
||||
case CODE_STRING:
|
||||
mySingletonMap.put(aKey, IoUtil.readString(aStream));
|
||||
mySingletonM.put(tmpKey, IoUtil.readString(aStream));
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
throw new RuntimeException("Unreconnized type: " + aType);
|
||||
throw new RuntimeException("Unreconnized type: " + tmpType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,55 +247,52 @@ public class PrimConfig
|
||||
*/
|
||||
public void writeBin(DataOutputStream aStream) throws IOException
|
||||
{
|
||||
Set<String> keySet;
|
||||
Object aVal;
|
||||
|
||||
keySet = mySingletonMap.keySet();
|
||||
|
||||
aStream.writeInt(keySet.size());
|
||||
for (String aKey : keySet)
|
||||
var keyS = mySingletonM.keySet();
|
||||
|
||||
aStream.writeInt(keyS.size());
|
||||
for (String aKey : keyS)
|
||||
{
|
||||
IoUtil.writeString(aStream, aKey);
|
||||
|
||||
aVal = mySingletonMap.get(aKey);
|
||||
if (aVal instanceof Boolean)
|
||||
|
||||
var tmpVal = mySingletonM.get(aKey);
|
||||
if (tmpVal instanceof Boolean)
|
||||
{
|
||||
aStream.writeByte(CODE_BOOL);
|
||||
aStream.writeBoolean((Boolean)aVal);
|
||||
aStream.writeBoolean((Boolean) tmpVal);
|
||||
}
|
||||
else if (aVal instanceof Integer)
|
||||
else if (tmpVal instanceof Integer)
|
||||
{
|
||||
aStream.writeByte(CODE_INT);
|
||||
aStream.writeInt((Integer)aVal);
|
||||
aStream.writeInt((Integer) tmpVal);
|
||||
}
|
||||
else if (aVal instanceof Long)
|
||||
else if (tmpVal instanceof Long)
|
||||
{
|
||||
aStream.writeByte(CODE_LONG);
|
||||
aStream.writeLong((Long)aVal);
|
||||
aStream.writeLong((Long) tmpVal);
|
||||
}
|
||||
else if (aVal instanceof Short)
|
||||
else if (tmpVal instanceof Short)
|
||||
{
|
||||
aStream.writeByte(CODE_SHORT);
|
||||
aStream.writeLong((Short)aVal);
|
||||
aStream.writeLong((Short) tmpVal);
|
||||
}
|
||||
else if (aVal instanceof Float)
|
||||
else if (tmpVal instanceof Float)
|
||||
{
|
||||
aStream.writeByte(CODE_FLOAT);
|
||||
aStream.writeFloat((Float)aVal);
|
||||
aStream.writeFloat((Float) tmpVal);
|
||||
}
|
||||
else if (aVal instanceof Double)
|
||||
else if (tmpVal instanceof Double)
|
||||
{
|
||||
aStream.writeByte(CODE_DOUBLE);
|
||||
aStream.writeDouble((Double)aVal);
|
||||
aStream.writeDouble((Double) tmpVal);
|
||||
}
|
||||
else if (aVal instanceof String)
|
||||
else if (tmpVal instanceof String)
|
||||
{
|
||||
aStream.writeByte(CODE_STRING);
|
||||
IoUtil.writeString(aStream, (String)aVal);
|
||||
IoUtil.writeString(aStream, (String) tmpVal);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new RuntimeException("Unsupported Object: " + aVal);
|
||||
throw new RuntimeException("Unsupported Object: " + tmpVal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +1,41 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import bibliothek.gui.dock.DockElement;
|
||||
|
||||
/**
|
||||
* Base class for Dockables which would like to store their configuration via
|
||||
* the PrimConfig mechanism. Note if the child class will be loaded with the
|
||||
* PrimDockableFactory, then you should have a constructor with one of the
|
||||
* following properties:.
|
||||
* <LI> 1 arguments: Registry
|
||||
* <LI> 0 arguments: Empty Constructor
|
||||
* <BR>
|
||||
* <BR>It is also important the method getFactoryID() is overridden so that it returns PrimDockableFactory.ID
|
||||
* Base class for Dockables which would like to store their configuration via the PrimConfig mechanism. Note if the
|
||||
* child class will be loaded with the PrimDockableFactory, then you should have a constructor with one of the following
|
||||
* properties:.
|
||||
* <ul>
|
||||
* <li>1 arguments: Registry
|
||||
* <li>0 arguments: Empty Constructor
|
||||
* </ul>
|
||||
* It is also important the method getFactoryID() is overridden so that it returns PrimDockableFactory.ID
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public interface PrimDock extends DockElement
|
||||
{
|
||||
/**
|
||||
* Returns the PrimConfig associated with the Dockable
|
||||
* @return
|
||||
* Returns the PrimConfig associated with the Dockable.
|
||||
*/
|
||||
public abstract PrimConfig getConfiguration();
|
||||
|
||||
/**
|
||||
* Configures the Dockable with the aConfig
|
||||
* @return
|
||||
* Configures the Dockable with the aConfig.
|
||||
*/
|
||||
public abstract void setConfiguration(PrimConfig aConfig);
|
||||
|
||||
|
||||
@@ -1,16 +1,25 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import glum.reflect.ReflectUtil;
|
||||
import glum.registry.Registry;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.collect.BiMap;
|
||||
import com.google.common.collect.HashBiMap;
|
||||
|
||||
import bibliothek.gui.Dockable;
|
||||
import bibliothek.gui.dock.DockFactory;
|
||||
import bibliothek.gui.dock.dockable.DefaultDockablePerspective;
|
||||
@@ -18,47 +27,52 @@ import bibliothek.gui.dock.layout.LocationEstimationMap;
|
||||
import bibliothek.gui.dock.perspective.PerspectiveDockable;
|
||||
import bibliothek.gui.dock.station.support.PlaceholderStrategy;
|
||||
import bibliothek.util.xml.XElement;
|
||||
import glum.reflect.ReflectUtil;
|
||||
import glum.registry.Registry;
|
||||
|
||||
/**
|
||||
* Generic DockableFactory for creating PrimDocks.
|
||||
* <P>
|
||||
* <p>
|
||||
* Note that before this factory is used all PrimDockable class types must first be associated with a spawnName. This is
|
||||
* used during serialization configuration associated with PrimDock. See method {@link PrimDockFactory#addSpawnMapping}
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class PrimDockFactory implements DockFactory<PrimDock, DefaultDockablePerspective, PrimConfig>
|
||||
{
|
||||
// Constants
|
||||
public static final String ID = "PrimDockFactory";
|
||||
public static final String SpawnNameKey = "factory.spawnName";
|
||||
|
||||
public static final String SpawnNameKey = "factory.spawnName";
|
||||
|
||||
// State var
|
||||
protected Registry refRegistry;
|
||||
protected BiMap<String, Class<? extends PrimDock>> spawnMap;
|
||||
|
||||
private Registry refRegistry;
|
||||
private BiMap<String, Class<? extends PrimDock>> spawnM;
|
||||
|
||||
/** Standard Constructor */
|
||||
public PrimDockFactory(Registry aRegistry)
|
||||
{
|
||||
refRegistry = aRegistry;
|
||||
spawnMap = HashBiMap.create();
|
||||
spawnM = HashBiMap.create();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a mapping for a PrimDockable to a the associated spawnName. It is mandatory
|
||||
* that this mapping is always the same regardless of application executions, as
|
||||
* this value will be serialized to the disk.
|
||||
* this value will be serialized to the disk.
|
||||
*/
|
||||
public void addSpawnMapping(String spawnName, Class<? extends PrimDock> spawnClass)
|
||||
public void addSpawnMapping(String aSpawnName, Class<? extends PrimDock> aSpawnClass)
|
||||
{
|
||||
// Ensure the spawnName is not already reserved
|
||||
if (spawnMap.containsKey(spawnName) == true)
|
||||
throw new RuntimeException("Previous mapping stored for spawnName:" + spawnName);
|
||||
|
||||
if (spawnM.containsKey(aSpawnName) == true)
|
||||
throw new RuntimeException("Previous mapping stored for spawnName:" + aSpawnName);
|
||||
|
||||
// Ensure the spawnClass is not already stored
|
||||
if (spawnMap.inverse().containsKey(spawnClass) == true)
|
||||
throw new RuntimeException("Previous mapping stored for spawnClass:" + spawnClass);
|
||||
|
||||
spawnMap.put(spawnName, spawnClass);
|
||||
if (spawnM.inverse().containsKey(aSpawnClass) == true)
|
||||
throw new RuntimeException("Previous mapping stored for spawnClass:" + aSpawnClass);
|
||||
|
||||
spawnM.put(aSpawnName, aSpawnClass);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getID()
|
||||
@@ -71,18 +85,18 @@ public class PrimDockFactory implements DockFactory<PrimDock, DefaultDockablePer
|
||||
{
|
||||
PrimConfig rConfig;
|
||||
String spawnName;
|
||||
|
||||
|
||||
rConfig = aDockable.getConfiguration();
|
||||
|
||||
|
||||
// Store the associated spawnName used to instantiate the Dockable
|
||||
spawnName = spawnMap.inverse().get(aDockable.getClass());
|
||||
spawnName = spawnM.inverse().get(aDockable.getClass());
|
||||
if (spawnName == null)
|
||||
throw new RuntimeException("Factory is not configured properly. Failed to locate associated spawnName for class:" + aDockable.getClass());
|
||||
|
||||
|
||||
// Ensure that the SpawnNameKey is not already reserved.
|
||||
; // TODO
|
||||
|
||||
rConfig.setString(SpawnNameKey, spawnName);
|
||||
|
||||
rConfig.setString(SpawnNameKey, spawnName);
|
||||
return rConfig;
|
||||
}
|
||||
|
||||
@@ -120,8 +134,8 @@ public class PrimDockFactory implements DockFactory<PrimDock, DefaultDockablePer
|
||||
@Override
|
||||
public PrimConfig read(DataInputStream aStream, PlaceholderStrategy placeholders) throws IOException
|
||||
{
|
||||
PrimConfig rLayout;
|
||||
|
||||
PrimConfig rLayout;
|
||||
|
||||
rLayout = new PrimConfig();
|
||||
rLayout.readBin(aStream);
|
||||
return rLayout;
|
||||
@@ -143,7 +157,7 @@ public class PrimDockFactory implements DockFactory<PrimDock, DefaultDockablePer
|
||||
public PrimDock layout(PrimConfig layout, Map<Integer, Dockable> children, PlaceholderStrategy placeholders)
|
||||
{
|
||||
PrimDock aDockable;
|
||||
|
||||
|
||||
aDockable = layout(layout, placeholders);
|
||||
return aDockable;
|
||||
}
|
||||
@@ -157,13 +171,13 @@ public class PrimDockFactory implements DockFactory<PrimDock, DefaultDockablePer
|
||||
Class<?> parmTypes[] = {Registry.class};
|
||||
Object parmValues[] = {refRegistry};
|
||||
String spawnName;
|
||||
|
||||
|
||||
spawnName = aLayout.getString(SpawnNameKey, null);
|
||||
|
||||
spawnClass = spawnMap.get(spawnName);
|
||||
|
||||
spawnClass = spawnM.get(spawnName);
|
||||
if (spawnClass == null)
|
||||
throw new RuntimeException("Factory is not configured properly. Failed to locate associated class for spawn name:" + spawnName);
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
spawnConstructor = ReflectUtil.getConstructorSafe(spawnClass, parmTypes);
|
||||
@@ -176,7 +190,7 @@ public class PrimDockFactory implements DockFactory<PrimDock, DefaultDockablePer
|
||||
{
|
||||
throw new RuntimeException("Failed to instantite class.", aExp);
|
||||
}
|
||||
|
||||
|
||||
rDockable.setConfiguration(aLayout);
|
||||
return rDockable;
|
||||
}
|
||||
@@ -189,7 +203,8 @@ public class PrimDockFactory implements DockFactory<PrimDock, DefaultDockablePer
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layoutPerspective(DefaultDockablePerspective perspective, PrimConfig layout, Map<Integer, PerspectiveDockable> children)
|
||||
public void layoutPerspective(DefaultDockablePerspective perspective, PrimConfig layout,
|
||||
Map<Integer, PerspectiveDockable> children)
|
||||
{
|
||||
; // Nothing to do
|
||||
}
|
||||
|
||||
@@ -1,14 +1,30 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock;
|
||||
|
||||
import bibliothek.gui.dock.DefaultDockable;
|
||||
|
||||
/**
|
||||
* Base class for Dockables which would like to store their configuration via
|
||||
* the PrimConfig mechanism. Note if the child class will be loaded with the
|
||||
* PrimDockableFactory, then you should have a constructor with one of the
|
||||
* following properties:.
|
||||
* <LI> 1 arguments: Registry
|
||||
* <LI> 0 arguments: Empty Constructor
|
||||
* Base class for Dockables which would like to store their configuration via the PrimConfig mechanism. Note if the
|
||||
* child class will be loaded with the PrimDockableFactory, then you should have a constructor with one of the following
|
||||
* properties:.
|
||||
* <ul>
|
||||
* <li>1 arguments: Registry
|
||||
* <li>0 arguments: Empty Constructor
|
||||
* </ul>
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public abstract class PrimDockable extends DefaultDockable implements PrimDock
|
||||
{
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.action;
|
||||
|
||||
public interface Closeable
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.action;
|
||||
|
||||
public interface Destroyable
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.action;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.action;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.action;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.action;
|
||||
|
||||
import javax.swing.Icon;
|
||||
@@ -7,21 +20,22 @@ import bibliothek.gui.dock.action.actions.SimpleButtonAction;
|
||||
|
||||
/**
|
||||
* An DockAction that will fire trigger an embedded java.awt Action
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class ToggleAction extends SimpleButtonAction
|
||||
{
|
||||
// State vars
|
||||
protected boolean isActive;
|
||||
|
||||
private boolean isActive;
|
||||
|
||||
// Gui vars
|
||||
protected Icon falseIcon, trueIcon;
|
||||
|
||||
private final Icon falseIcon, trueIcon;
|
||||
|
||||
/** Standard Constructor */
|
||||
public ToggleAction(String aText, Icon aFalseIcon, Icon aTrueIcon, boolean aIsActive)
|
||||
{
|
||||
super();
|
||||
|
||||
isActive = aIsActive;
|
||||
|
||||
|
||||
falseIcon = aFalseIcon;
|
||||
trueIcon = aTrueIcon;
|
||||
|
||||
@@ -36,24 +50,24 @@ public class ToggleAction extends SimpleButtonAction
|
||||
{
|
||||
return isActive;
|
||||
}
|
||||
|
||||
|
||||
public void setIsActive(boolean aBool)
|
||||
{
|
||||
isActive = aBool;
|
||||
updateGui();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void action(Dockable aDockable)
|
||||
{
|
||||
isActive = !isActive;
|
||||
updateGui();
|
||||
|
||||
|
||||
super.action(aDockable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method
|
||||
* Utility method
|
||||
*/
|
||||
private void updateGui()
|
||||
{
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.alt;
|
||||
|
||||
import glum.gui.dock.action.Destroyable;
|
||||
|
||||
@@ -1,42 +1,58 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.alt;
|
||||
|
||||
import glum.gui.dock.BaseDockable;
|
||||
|
||||
import java.awt.Window;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import bibliothek.gui.Dockable;
|
||||
import bibliothek.gui.dock.ScreenDockStation;
|
||||
import bibliothek.gui.dock.action.DefaultDockActionSource;
|
||||
import bibliothek.gui.dock.action.DockAction;
|
||||
import bibliothek.gui.dock.action.DockActionSource;
|
||||
import bibliothek.gui.dock.action.LocationHint;
|
||||
import glum.gui.dock.BaseDockable;
|
||||
|
||||
/**
|
||||
* Alternative ScreenDockStation which provides no default direct/indirect action offers.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class AltScreenDockStation extends ScreenDockStation
|
||||
{
|
||||
// Action vars
|
||||
private List<DockAction> directDockActionList;
|
||||
private List<DockAction> indirectDockActionList;
|
||||
private List<DockAction> directDockActionL;
|
||||
private List<DockAction> indirectDockActionL;
|
||||
|
||||
// Lock vars
|
||||
private Set<Dockable> lockSet;
|
||||
private Set<Dockable> lockS;
|
||||
private boolean isLocked;
|
||||
|
||||
public AltScreenDockStation(Window owner)
|
||||
/**
|
||||
* Standard Constructor
|
||||
*/
|
||||
public AltScreenDockStation(Window aOwner)
|
||||
{
|
||||
super(owner);
|
||||
super(aOwner);
|
||||
|
||||
directDockActionList = Lists.newArrayList();
|
||||
indirectDockActionList = Lists.newArrayList();
|
||||
directDockActionL = new ArrayList<>();
|
||||
indirectDockActionL = new ArrayList<>();
|
||||
|
||||
lockSet = Sets.newHashSet();
|
||||
lockS = new HashSet<>();
|
||||
isLocked = false;
|
||||
}
|
||||
|
||||
@@ -45,7 +61,7 @@ public class AltScreenDockStation extends ScreenDockStation
|
||||
*/
|
||||
public void addDirectActionOffer(DockAction aDockAction)
|
||||
{
|
||||
directDockActionList.add(aDockAction);
|
||||
directDockActionL.add(aDockAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,7 +69,7 @@ public class AltScreenDockStation extends ScreenDockStation
|
||||
*/
|
||||
public void addIndirectActionOffer(DockAction aDockAction)
|
||||
{
|
||||
indirectDockActionList.add(aDockAction);
|
||||
indirectDockActionL.add(aDockAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,14 +82,14 @@ public class AltScreenDockStation extends ScreenDockStation
|
||||
|
||||
if (isLocked == false)
|
||||
{
|
||||
lockSet.clear();
|
||||
lockS.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Record all of the valid children when the lock is triggered
|
||||
for (int c1 = 0; c1 < getDockableCount(); c1++)
|
||||
{
|
||||
lockSet.add(getDockable(c1));
|
||||
lockS.add(getDockable(c1));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -82,34 +98,34 @@ public class AltScreenDockStation extends ScreenDockStation
|
||||
public boolean accept(Dockable aChild)
|
||||
{
|
||||
// If we are locked then never accept any Dockable, which was not recorded as valid when the lock happened
|
||||
if (isLocked == true && lockSet.contains(aChild) == false)
|
||||
if (isLocked == true && lockS.contains(aChild) == false)
|
||||
return false;
|
||||
|
||||
// Never accept any Dockable that has been marked as nontransferable
|
||||
if (aChild instanceof BaseDockable)
|
||||
return ((BaseDockable)aChild).isTransferable(this);
|
||||
return ((BaseDockable) aChild).isTransferable(this);
|
||||
|
||||
return super.accept(aChild);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultDockActionSource getDirectActionOffers(Dockable dockable)
|
||||
public DefaultDockActionSource getDirectActionOffers(Dockable aDockable)
|
||||
{
|
||||
DefaultDockActionSource source;
|
||||
|
||||
source = new DefaultDockActionSource(new LocationHint(LocationHint.DIRECT_ACTION, LocationHint.VERY_RIGHT));
|
||||
source.add(directDockActionList.toArray(new DockAction[0]));
|
||||
source.add(directDockActionL.toArray(new DockAction[0]));
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DockActionSource getIndirectActionOffers(Dockable dockable)
|
||||
public DockActionSource getIndirectActionOffers(Dockable aDockable)
|
||||
{
|
||||
DefaultDockActionSource source;
|
||||
|
||||
source = new DefaultDockActionSource(new LocationHint(LocationHint.INDIRECT_ACTION, LocationHint.VERY_RIGHT));
|
||||
source.add(indirectDockActionList.toArray(new DockAction[0]));
|
||||
source.add(indirectDockActionL.toArray(new DockAction[0]));
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.alt;
|
||||
|
||||
import java.awt.Dialog;
|
||||
|
||||
@@ -1,39 +1,49 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.dock.alt;
|
||||
|
||||
import glum.gui.dock.BaseDockable;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import java.util.*;
|
||||
|
||||
import bibliothek.gui.Dockable;
|
||||
import bibliothek.gui.dock.SplitDockStation;
|
||||
import bibliothek.gui.dock.action.DefaultDockActionSource;
|
||||
import bibliothek.gui.dock.action.DockAction;
|
||||
import bibliothek.gui.dock.action.DockActionSource;
|
||||
import bibliothek.gui.dock.action.LocationHint;
|
||||
import bibliothek.gui.dock.action.*;
|
||||
import glum.gui.dock.BaseDockable;
|
||||
|
||||
/**
|
||||
* Alternative implementation of SplitDockStation.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class AltSplitDockStation extends SplitDockStation
|
||||
{
|
||||
// Action vars
|
||||
private List<DockAction> directDockActionList;
|
||||
private List<DockAction> localDockActionList;
|
||||
private List<DockAction> indirectDockActionList;
|
||||
private List<DockAction> directDockActionL;
|
||||
private List<DockAction> localDockActionL;
|
||||
private List<DockAction> indirectDockActionL;
|
||||
|
||||
// Lock vars
|
||||
private Set<Dockable> lockSet;
|
||||
private Set<Dockable> lockS;
|
||||
private boolean isLocked;
|
||||
|
||||
/** Standard Constructor */
|
||||
public AltSplitDockStation()
|
||||
{
|
||||
super();
|
||||
directDockActionL = new ArrayList<>();
|
||||
localDockActionL = new ArrayList<>();
|
||||
indirectDockActionL = new ArrayList<>();
|
||||
|
||||
directDockActionList = Lists.newArrayList();
|
||||
localDockActionList = Lists.newArrayList();
|
||||
indirectDockActionList = Lists.newArrayList();
|
||||
|
||||
lockSet = Sets.newHashSet();
|
||||
lockS = new HashSet<>();
|
||||
isLocked = false;
|
||||
}
|
||||
|
||||
@@ -42,7 +52,7 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
*/
|
||||
public void addDirectActionOffer(DockAction aDockAction)
|
||||
{
|
||||
directDockActionList.add(aDockAction);
|
||||
directDockActionL.add(aDockAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,7 +60,7 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
*/
|
||||
public void addLocalActionOffer(DockAction aDockAction)
|
||||
{
|
||||
localDockActionList.add(aDockAction);
|
||||
localDockActionL.add(aDockAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,7 +68,7 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
*/
|
||||
public void addIndirectActionOffer(DockAction aDockAction)
|
||||
{
|
||||
indirectDockActionList.add(aDockAction);
|
||||
indirectDockActionL.add(aDockAction);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,14 +81,14 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
|
||||
if (isLocked == false)
|
||||
{
|
||||
lockSet.clear();
|
||||
lockS.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
// Record all of the valid children when the lock is triggered
|
||||
for (int c1 = 0; c1 < getDockableCount(); c1++)
|
||||
{
|
||||
lockSet.add(getDockable(c1));
|
||||
lockS.add(getDockable(c1));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -87,18 +97,18 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
public boolean accept(Dockable aChild)
|
||||
{
|
||||
// If we are locked then never accept any Dockable, which was not recorded as valid when the lock happened
|
||||
if (isLocked == true && lockSet.contains(aChild) == false)
|
||||
if (isLocked == true && lockS.contains(aChild) == false)
|
||||
return false;
|
||||
|
||||
// Never accept any Dockable that has been marked as nontransferable
|
||||
if (aChild instanceof BaseDockable)
|
||||
return ((BaseDockable)aChild).isTransferable(this);
|
||||
return ((BaseDockable) aChild).isTransferable(this);
|
||||
|
||||
// Default behavior for non BaseDockables
|
||||
return super.accept(aChild);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// @Override
|
||||
// protected boolean acceptable(Dockable old, Dockable next)
|
||||
// {
|
||||
@@ -112,8 +122,8 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
//// if (((BaseDockable)next).isTransferable() == false)
|
||||
//// return false;
|
||||
//// }
|
||||
////
|
||||
////
|
||||
////
|
||||
////
|
||||
//// // TODO Auto-generated method stub
|
||||
//// return super.acceptable(old, next);
|
||||
// }
|
||||
@@ -127,7 +137,7 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
// return super.canDrag(aDockable);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// @Override
|
||||
// public boolean canReplace(Dockable oldDockable, Dockable nextDockable)
|
||||
// {
|
||||
@@ -141,12 +151,10 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
// }
|
||||
|
||||
@Override
|
||||
public DefaultDockActionSource getDirectActionOffers(Dockable dockable)
|
||||
public DefaultDockActionSource getDirectActionOffers(Dockable aDockable)
|
||||
{
|
||||
DefaultDockActionSource source;
|
||||
|
||||
source = new DefaultDockActionSource(new LocationHint(LocationHint.DIRECT_ACTION, LocationHint.VERY_RIGHT));
|
||||
source.add(directDockActionList.toArray(new DockAction[0]));
|
||||
var source = new DefaultDockActionSource(new LocationHint(LocationHint.DIRECT_ACTION, LocationHint.VERY_RIGHT));
|
||||
source.add(directDockActionL.toArray(new DockAction[0]));
|
||||
|
||||
return source;
|
||||
}
|
||||
@@ -154,21 +162,17 @@ public class AltSplitDockStation extends SplitDockStation
|
||||
@Override
|
||||
public DockActionSource getLocalActionOffers()
|
||||
{
|
||||
DefaultDockActionSource source;
|
||||
|
||||
source = new DefaultDockActionSource(new LocationHint(LocationHint.DOCKABLE, LocationHint.RIGHT));
|
||||
source.add(localDockActionList.toArray(new DockAction[0]));
|
||||
var source = new DefaultDockActionSource(new LocationHint(LocationHint.DOCKABLE, LocationHint.RIGHT));
|
||||
source.add(localDockActionL.toArray(new DockAction[0]));
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DockActionSource getIndirectActionOffers(Dockable dockable)
|
||||
public DockActionSource getIndirectActionOffers(Dockable aDockable)
|
||||
{
|
||||
DefaultDockActionSource source;
|
||||
|
||||
source = new DefaultDockActionSource(new LocationHint(LocationHint.INDIRECT_ACTION, LocationHint.VERY_RIGHT));
|
||||
source.add(indirectDockActionList.toArray(new DockAction[0]));
|
||||
var source = new DefaultDockActionSource(new LocationHint(LocationHint.INDIRECT_ACTION, LocationHint.VERY_RIGHT));
|
||||
source.add(indirectDockActionL.toArray(new DockAction[0]));
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,38 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.document;
|
||||
|
||||
import java.awt.event.*;
|
||||
import javax.swing.text.*;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.text.PlainDocument;
|
||||
|
||||
public abstract class BaseDocument extends PlainDocument implements ActionListener, FocusListener
|
||||
{
|
||||
// State vars
|
||||
protected JTextField ownerTF;
|
||||
|
||||
/** Standard Constructor */
|
||||
public BaseDocument(JTextField aOwnerTF)
|
||||
{
|
||||
super();
|
||||
|
||||
ownerTF = aOwnerTF;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the owner of this Document model
|
||||
* Todo: This method should no longer be needed.
|
||||
* <p>
|
||||
* TODO: This method should no longer be needed.
|
||||
*/
|
||||
public JTextField getOwner()
|
||||
{
|
||||
|
||||
@@ -1,23 +1,40 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.document;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
|
||||
/**
|
||||
* Implementation of {@link BaseDocument} specific for numerical input.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public abstract class BaseNumberDocument extends BaseDocument
|
||||
{
|
||||
// State vars
|
||||
protected double minVal, maxVal;
|
||||
protected boolean formalizeDoc;
|
||||
protected int numAvailCols;
|
||||
|
||||
/** Standard Constructor */
|
||||
public BaseNumberDocument(JTextField aOwner, double aMinVal, double aMaxVal)
|
||||
{
|
||||
super(aOwner);
|
||||
|
||||
|
||||
setMinMaxValue(aMinVal, aMaxVal);
|
||||
formalizeDoc = false;
|
||||
numAvailCols = -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the new range of valid numbers.
|
||||
*/
|
||||
@@ -25,12 +42,12 @@ public abstract class BaseNumberDocument extends BaseDocument
|
||||
{
|
||||
minVal = aMinVal;
|
||||
maxVal = aMaxVal;
|
||||
|
||||
|
||||
// Insanity check
|
||||
if (minVal >= maxVal)
|
||||
throw new RuntimeException("Illogical range. Range: [" + minVal + "," + maxVal + "]");
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void formalizeInput()
|
||||
{
|
||||
@@ -56,6 +73,4 @@ public abstract class BaseNumberDocument extends BaseDocument
|
||||
ownerTF.addFocusListener(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,37 +1,49 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.document;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.BadLocationException;
|
||||
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
/**
|
||||
* Specialized Document designed to accept only the specified input chars
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class CharDocument extends BaseDocument
|
||||
{
|
||||
private Set<Character> validSet;
|
||||
private Set<Character> validS;
|
||||
|
||||
public CharDocument(JTextField aOwner, String validCharStr)
|
||||
{
|
||||
this(aOwner, validCharStr, true);
|
||||
}
|
||||
|
||||
public CharDocument(JTextField aOwner, String validCharStr, boolean isCaseSensitive)
|
||||
/**
|
||||
* Standard Constructor
|
||||
*/
|
||||
public CharDocument(JTextField aOwner, String aValidCharStr, boolean aIsCaseSensitive)
|
||||
{
|
||||
super(aOwner);
|
||||
|
||||
validSet = Sets.newHashSet();
|
||||
for (int c1 = 0; c1 < validCharStr.length(); c1++)
|
||||
|
||||
validS = new HashSet<>();
|
||||
for (int c1 = 0; c1 < aValidCharStr.length(); c1++)
|
||||
{
|
||||
validSet.add(validCharStr.charAt(c1));
|
||||
if (isCaseSensitive == false)
|
||||
validS.add(aValidCharStr.charAt(c1));
|
||||
if (aIsCaseSensitive == false)
|
||||
{
|
||||
validSet.add(Character.toLowerCase(validCharStr.charAt(c1)));
|
||||
validSet.add(Character.toUpperCase(validCharStr.charAt(c1)));
|
||||
validS.add(Character.toLowerCase(aValidCharStr.charAt(c1)));
|
||||
validS.add(Character.toUpperCase(aValidCharStr.charAt(c1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -41,25 +53,23 @@ public class CharDocument extends BaseDocument
|
||||
{
|
||||
; // Nothing to do
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
|
||||
{
|
||||
char aChar;
|
||||
|
||||
@Override
|
||||
public void insertString(int aOffs, String aStr, AttributeSet aAS) throws BadLocationException
|
||||
{
|
||||
// Insanity check
|
||||
if (str == null)
|
||||
if (aStr == null)
|
||||
return;
|
||||
|
||||
|
||||
// Ensure all of the characters in str are in the valid set
|
||||
for (int c1 = 0; c1 < str.length(); c1++)
|
||||
for (int c1 = 0; c1 < aStr.length(); c1++)
|
||||
{
|
||||
aChar = str.charAt(c1);
|
||||
if (validSet.contains(aChar) == false)
|
||||
throw new BadLocationException("Invalid character: " + aChar, offs);
|
||||
char tmpChar = aStr.charAt(c1);
|
||||
if (validS.contains(tmpChar) == false)
|
||||
throw new BadLocationException("Invalid character: " + tmpChar, aOffs);
|
||||
}
|
||||
|
||||
super.insertString(offs, str, a);
|
||||
|
||||
super.insertString(aOffs, aStr, aAS);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.document;
|
||||
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.BadLocationException;
|
||||
|
||||
import glum.gui.GuiUtil;
|
||||
import glum.io.ParseUtil;
|
||||
|
||||
/**
|
||||
* Implementation of {@link BaseNumberDocument}.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class NumberDocument extends BaseNumberDocument
|
||||
{
|
||||
protected boolean allowFloats;
|
||||
// protected NumberUnit myUnit;
|
||||
// Constants
|
||||
private final String ValidPosDigitStr = "0123456789";
|
||||
private final String ValidNegDigitStr = "+-0123456789";
|
||||
private final String ValidFractStr = "+-0123456789e.";
|
||||
|
||||
protected boolean allowFloats;
|
||||
// protected NumberUnit myUnit;
|
||||
|
||||
/** Standard Constructor */
|
||||
public NumberDocument(JTextField aOwnerTF, boolean aFormalizeDoc)
|
||||
{
|
||||
super(aOwnerTF, Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY);
|
||||
@@ -38,6 +63,28 @@ public class NumberDocument extends BaseNumberDocument
|
||||
if (str == null)
|
||||
return;
|
||||
|
||||
// Change to allow user to enter any valid single character to be input. Note that the
|
||||
// NumberDocument is used primary by GNumberField and as such invalid input will be
|
||||
// colored with the "fail" color.
|
||||
if (str.length() == 1)
|
||||
{
|
||||
if (allowFloats == false && minVal >= 0 && ValidPosDigitStr.contains(str) == true)
|
||||
{
|
||||
super.insertString(offs, str, a);
|
||||
return;
|
||||
}
|
||||
else if (allowFloats == false && minVal < 0 && ValidNegDigitStr.contains(str) == true)
|
||||
{
|
||||
super.insertString(offs, str, a);
|
||||
return;
|
||||
}
|
||||
else if (allowFloats == true && ValidFractStr.contains(str) == true)
|
||||
{
|
||||
super.insertString(offs, str, a);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Special cases
|
||||
aChar = str.charAt(0);
|
||||
if (offs == 0)
|
||||
@@ -76,13 +123,6 @@ public class NumberDocument extends BaseNumberDocument
|
||||
if (str.contains(".") == true && allowFloats == false)
|
||||
throw new BadLocationException("Only integers are allowed.", offs);
|
||||
|
||||
// Ensure we do not exceed number of columns
|
||||
if (numAvailCols > 0)
|
||||
{
|
||||
if (offs + str.length() >= numAvailCols)
|
||||
throw new BadLocationException("Too many characters to insert.", offs);
|
||||
}
|
||||
|
||||
// Form the resultant string
|
||||
bStr = "";
|
||||
eStr = "";
|
||||
@@ -92,7 +132,7 @@ public class NumberDocument extends BaseNumberDocument
|
||||
resultStr = bStr + str + eStr;
|
||||
|
||||
// Ensure the resultant is sensical
|
||||
aVal = GuiUtil.readDouble(resultStr, Double.NaN);
|
||||
aVal = ParseUtil.readDouble(resultStr, Double.NaN);
|
||||
if (Double.isNaN(aVal) == true)
|
||||
throw new BadLocationException("Nonsensical number.", offs);
|
||||
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.icon;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.icon;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.icon;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.icon;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.icon;
|
||||
|
||||
import java.awt.Component;
|
||||
@@ -5,11 +18,28 @@ import java.awt.Graphics;
|
||||
|
||||
import javax.swing.Icon;
|
||||
|
||||
/**
|
||||
* Immutable icon that renders nothing.
|
||||
* <p>
|
||||
* This icon will typically be used as a place holder.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class EmptyIcon implements Icon
|
||||
{
|
||||
protected int width, height;
|
||||
|
||||
EmptyIcon(int aWidth, int aHeight)
|
||||
// Attributes
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
/**
|
||||
* Standard Constructor
|
||||
*
|
||||
* @param aWidth
|
||||
* The width of the icon.
|
||||
* @param aHeight
|
||||
* The height of the icon.
|
||||
*/
|
||||
public EmptyIcon(int aWidth, int aHeight)
|
||||
{
|
||||
width = aWidth;
|
||||
height = aHeight;
|
||||
|
||||
@@ -1,24 +1,45 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.icon;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.net.URL;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
import javax.swing.JButton;
|
||||
|
||||
/**
|
||||
* Collection of utility methods for dealing with icons.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class IconUtil
|
||||
{
|
||||
/**
|
||||
* Utility method to load the Icon specified by the resource path.
|
||||
* Utility method to load an icon from the specified resource.
|
||||
*/
|
||||
public static ImageIcon loadIcon(String iconPath)
|
||||
public static ImageIcon loadIcon(String aIconPath)
|
||||
{
|
||||
// URL aURL;
|
||||
//
|
||||
// aURL = IconUtil.class.getClassLoader().getResource(iconPath);
|
||||
// if (aURL == null)
|
||||
// throw new RuntimeException("Failed to load icon for path: " + iconPath);
|
||||
//
|
||||
// return new ImageIcon(aURL);
|
||||
return new ImageIcon(ClassLoader.getSystemResource(iconPath));
|
||||
return new ImageIcon(ClassLoader.getSystemResource(aIconPath));
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to load an icon from the specified resource.
|
||||
*/
|
||||
public static ImageIcon loadIcon(URL aURL)
|
||||
{
|
||||
return new ImageIcon(aURL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,8 +49,8 @@ public class IconUtil
|
||||
{
|
||||
if (aComp instanceof JButton == false)
|
||||
return false;
|
||||
|
||||
return ((JButton)aComp).getModel().isPressed();
|
||||
|
||||
return ((JButton) aComp).getModel().isPressed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.info;
|
||||
|
||||
import glum.zio.*;
|
||||
|
||||
162
src/glum/gui/info/WindowCfg.java
Normal file
162
src/glum/gui/info/WindowCfg.java
Normal file
@@ -0,0 +1,162 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.info;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.io.IOException;
|
||||
|
||||
import glum.zio.*;
|
||||
|
||||
/**
|
||||
* Immutable object used to store the position/dimension/visibility state of a {@link Component}.
|
||||
* <p>
|
||||
* This is typically used capture the state of a dialog or window.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class WindowCfg implements ZioRaw
|
||||
{
|
||||
// Attributes
|
||||
private final boolean isShown;
|
||||
private final int posX;
|
||||
private final int posY;
|
||||
private final int dimX;
|
||||
private final int dimY;
|
||||
|
||||
/** Standard Constructor */
|
||||
public WindowCfg(boolean aIsShown, int aPosX, int aPosY, int aDimX, int aDimY)
|
||||
{
|
||||
isShown = aIsShown;
|
||||
|
||||
posX = aPosX;
|
||||
posY = aPosY;
|
||||
|
||||
dimX = aDimX;
|
||||
dimY = aDimY;
|
||||
}
|
||||
|
||||
/** Serialization Constructor */
|
||||
public WindowCfg(ZinStream aStream) throws IOException
|
||||
{
|
||||
aStream.readVersion(0);
|
||||
|
||||
isShown = aStream.readBool();
|
||||
|
||||
posX = aStream.readInt();
|
||||
posY = aStream.readInt();
|
||||
|
||||
dimX = aStream.readInt();
|
||||
dimY = aStream.readInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* UI based constructor
|
||||
*
|
||||
* The WindowInfo will be setup to the current state of the provided {@link Component}.
|
||||
*/
|
||||
public WindowCfg(Component aComponent)
|
||||
{
|
||||
isShown = aComponent.isVisible();
|
||||
|
||||
posX = aComponent.getLocation().x;
|
||||
posY = aComponent.getLocation().y;
|
||||
|
||||
dimX = aComponent.getSize().width;
|
||||
dimY = aComponent.getSize().height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Syncs the specified {@link Component} to match the state of this {@link WindowCfg}.
|
||||
*/
|
||||
public void configure(Component aComponent)
|
||||
{
|
||||
aComponent.setLocation(posX, posY);
|
||||
|
||||
aComponent.setPreferredSize(new Dimension(dimX, dimY));
|
||||
aComponent.setSize(dimX, dimY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link WindowCfg} which matches this WindowInfo but with the isShown flag set to the requested setting.
|
||||
*/
|
||||
public WindowCfg withIsShown(boolean aIsShown)
|
||||
{
|
||||
// Bail if nothing changes
|
||||
if (isShown == aIsShown)
|
||||
return this;
|
||||
|
||||
return new WindowCfg(aIsShown, posX, posY, dimX, dimY);
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
// Accessor methods
|
||||
public boolean isShown() { return isShown; }
|
||||
public int dimX() { return dimX; }
|
||||
public int dimY() { return dimY; }
|
||||
public int posX() { return posX; }
|
||||
public int posY() { return posY; }
|
||||
// @formatter:on
|
||||
|
||||
@Override
|
||||
public void zioWrite(ZoutStream aStream) throws IOException
|
||||
{
|
||||
aStream.writeVersion(0);
|
||||
|
||||
aStream.writeBool(isShown);
|
||||
|
||||
aStream.writeInt(posX);
|
||||
aStream.writeInt(posY);
|
||||
|
||||
aStream.writeInt(dimX);
|
||||
aStream.writeInt(dimY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
final int prime = 31;
|
||||
int result = 1;
|
||||
result = prime * result + dimX;
|
||||
result = prime * result + dimY;
|
||||
result = prime * result + (isShown ? 1231 : 1237);
|
||||
result = prime * result + posX;
|
||||
result = prime * result + posY;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
WindowCfg other = (WindowCfg) obj;
|
||||
if (dimX != other.dimX)
|
||||
return false;
|
||||
if (dimY != other.dimY)
|
||||
return false;
|
||||
if (isShown != other.isShown)
|
||||
return false;
|
||||
if (posX != other.posX)
|
||||
return false;
|
||||
if (posY != other.posY)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package glum.gui.info;
|
||||
|
||||
import glum.zio.*;
|
||||
import glum.zio.util.ZioUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
|
||||
public class WindowInfo implements ZioObj
|
||||
{
|
||||
// Raw vars
|
||||
protected Point position;
|
||||
protected Dimension size;
|
||||
protected boolean isVisible;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public WindowInfo()
|
||||
{
|
||||
position = null;
|
||||
size = null;
|
||||
isVisible = false;
|
||||
}
|
||||
|
||||
public WindowInfo(Component aComponent)
|
||||
{
|
||||
this();
|
||||
|
||||
if (aComponent == null)
|
||||
return;
|
||||
|
||||
position = aComponent.getLocation();
|
||||
size = aComponent.getSize();
|
||||
isVisible = aComponent.isVisible();
|
||||
}
|
||||
|
||||
/**
|
||||
* configure - Syncs aComponent with parmaters of this WindowInfo
|
||||
*/
|
||||
public void configure(Component aComponent)
|
||||
{
|
||||
if (position != null)
|
||||
aComponent.setLocation(position);
|
||||
|
||||
if (size != null)
|
||||
{
|
||||
aComponent.setPreferredSize(size);
|
||||
aComponent.setSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zioRead(ZinStream aStream) throws IOException
|
||||
{
|
||||
aStream.readVersion(0);
|
||||
|
||||
isVisible = aStream.readBool();
|
||||
|
||||
position = ZioUtil.readPoint(aStream);
|
||||
|
||||
size = ZioUtil.readDimension(aStream);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void zioWrite(ZoutStream aStream) throws IOException
|
||||
{
|
||||
aStream.writeVersion(0);
|
||||
|
||||
aStream.writeBool(isVisible);
|
||||
|
||||
ZioUtil.writePoint(aStream, position);
|
||||
|
||||
ZioUtil.writeDimension(aStream, size);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,20 +1,36 @@
|
||||
package glum.gui.dialog;
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.memory;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import javax.swing.*;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
import glum.gui.FocusUtil;
|
||||
import glum.gui.GuiUtil;
|
||||
import glum.gui.action.ClickAction;
|
||||
import glum.gui.component.GLabel;
|
||||
import glum.unit.ConstUnitProvider;
|
||||
import glum.unit.NumberUnit;
|
||||
import glum.unit.UnitProvider;
|
||||
import glum.unit.*;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
|
||||
/**
|
||||
* UI componet that provides a view of the applications memory state.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class MemoryUtilDialog extends JDialog implements ActionListener
|
||||
{
|
||||
// Gui components
|
||||
@@ -23,7 +39,7 @@ public class MemoryUtilDialog extends JDialog implements ActionListener
|
||||
private JButton closeB, gcRunB, updateB;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* Standard Constructor
|
||||
*/
|
||||
public MemoryUtilDialog(JFrame parentFrame)
|
||||
{
|
||||
@@ -33,8 +49,7 @@ public class MemoryUtilDialog extends JDialog implements ActionListener
|
||||
setDefaultCloseOperation(HIDE_ON_CLOSE);
|
||||
setModal(false);
|
||||
|
||||
DecimalFormat numFormat;
|
||||
numFormat = new DecimalFormat();
|
||||
var numFormat = new DecimalFormat();
|
||||
numFormat.setGroupingUsed(true);
|
||||
numFormat.setGroupingSize(3);
|
||||
numFormat.setMaximumFractionDigits(0);
|
||||
@@ -52,9 +67,7 @@ public class MemoryUtilDialog extends JDialog implements ActionListener
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e)
|
||||
{
|
||||
Object source;
|
||||
|
||||
source = e.getSource();
|
||||
var source = e.getSource();
|
||||
if (source == gcRunB)
|
||||
{
|
||||
System.gc();
|
||||
@@ -82,40 +95,36 @@ public class MemoryUtilDialog extends JDialog implements ActionListener
|
||||
*/
|
||||
private void buildGuiArea()
|
||||
{
|
||||
JPanel aPanel;
|
||||
JLabel tmpL;
|
||||
Font tmpFont;
|
||||
|
||||
// Form the panel
|
||||
aPanel = new JPanel(new MigLayout("", "[right][left,grow]", "[][][]10[]10"));
|
||||
tmpFont = new JTextField().getFont();
|
||||
var tmpPanel = new JPanel(new MigLayout("", "[right][left,grow]", "[][][]10[]10"));
|
||||
var tmpFont = new JTextField().getFont();
|
||||
|
||||
// Info area
|
||||
tmpL = new JLabel("Total Memory:");
|
||||
var tmpL = new JLabel("Total Memory:");
|
||||
totalMemL = new GLabel(byteUP, tmpFont, true);
|
||||
aPanel.add(tmpL, "");
|
||||
aPanel.add(totalMemL, "growx,wrap");
|
||||
tmpPanel.add(tmpL, "");
|
||||
tmpPanel.add(totalMemL, "growx,wrap");
|
||||
|
||||
tmpL = new JLabel("Free Memory:");
|
||||
freeMemL = new GLabel(byteUP, tmpFont, true);
|
||||
aPanel.add(tmpL, "");
|
||||
aPanel.add(freeMemL, "growx,wrap");
|
||||
tmpPanel.add(tmpL, "");
|
||||
tmpPanel.add(freeMemL, "growx,wrap");
|
||||
|
||||
tmpL = new JLabel("Used Memory:");
|
||||
usedMemL = new GLabel(byteUP, tmpFont, true);
|
||||
aPanel.add(tmpL, "");
|
||||
aPanel.add(usedMemL, "growx,wrap");
|
||||
tmpPanel.add(tmpL, "");
|
||||
tmpPanel.add(usedMemL, "growx,wrap");
|
||||
|
||||
// Control area
|
||||
updateB = GuiUtil.createJButton("Update", this);
|
||||
gcRunB = GuiUtil.createJButton("Run GC", this);
|
||||
closeB = GuiUtil.createJButton("Close", this);
|
||||
aPanel.add(updateB, "span 2,split 3");
|
||||
aPanel.add(gcRunB, "");
|
||||
aPanel.add(closeB, "");
|
||||
tmpPanel.add(updateB, "span 2,split 3");
|
||||
tmpPanel.add(gcRunB, "");
|
||||
tmpPanel.add(closeB, "");
|
||||
|
||||
// Add the main panel into the dialog
|
||||
getContentPane().add(aPanel);
|
||||
getContentPane().add(tmpPanel);
|
||||
pack();
|
||||
}
|
||||
|
||||
@@ -124,15 +133,12 @@ public class MemoryUtilDialog extends JDialog implements ActionListener
|
||||
*/
|
||||
private void updateGui()
|
||||
{
|
||||
Runtime aRuntime;
|
||||
long freeMem, usedMem, totalMem;
|
||||
|
||||
aRuntime = Runtime.getRuntime();
|
||||
var tmpRuntime = Runtime.getRuntime();
|
||||
|
||||
// Update the memory usage
|
||||
freeMem = aRuntime.freeMemory();
|
||||
totalMem = aRuntime.totalMemory();
|
||||
usedMem = totalMem - freeMem;
|
||||
var freeMem = tmpRuntime.freeMemory();
|
||||
var totalMem = tmpRuntime.totalMemory();
|
||||
var usedMem = totalMem - freeMem;
|
||||
|
||||
freeMemL.setValue(freeMem);
|
||||
totalMemL.setValue(totalMem);
|
||||
@@ -1,3 +1,16 @@
|
||||
// Copyright (C) 2024 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
package glum.gui.misc;
|
||||
|
||||
import java.awt.Component;
|
||||
@@ -5,43 +18,47 @@ import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import javax.swing.AbstractCellEditor;
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JTable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.TableCellEditor;
|
||||
|
||||
/**
|
||||
* Cell editor suitable for editing boolean values.
|
||||
*
|
||||
* @author lopeznr1
|
||||
*/
|
||||
public class BooleanCellEditor extends AbstractCellEditor implements ActionListener, TableCellEditor
|
||||
{
|
||||
// State vars
|
||||
protected Collection<ActionListener> myListeners;
|
||||
protected JCheckBox refCheckBox;
|
||||
private Collection<ActionListener> listenerL;
|
||||
private JCheckBox refCheckBox;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
/** Standard Constructor */
|
||||
public BooleanCellEditor(ActionListener aListener)
|
||||
{
|
||||
listenerL = new LinkedList<>();
|
||||
if (aListener != null)
|
||||
listenerL.add(aListener);
|
||||
|
||||
refCheckBox = new JCheckBox("", false);
|
||||
refCheckBox.addActionListener(this);
|
||||
refCheckBox.setHorizontalAlignment(JCheckBox.CENTER);
|
||||
}
|
||||
|
||||
/** Simplified Constructor */
|
||||
public BooleanCellEditor()
|
||||
{
|
||||
this(null);
|
||||
}
|
||||
|
||||
public BooleanCellEditor(ActionListener aListener)
|
||||
{
|
||||
myListeners = new LinkedList<ActionListener>();
|
||||
if (aListener != null)
|
||||
myListeners.add(aListener);
|
||||
|
||||
refCheckBox = new JCheckBox("", false);
|
||||
refCheckBox.addActionListener(this);
|
||||
}
|
||||
|
||||
public void addActionListener(ActionListener aListener)
|
||||
{
|
||||
myListeners.add(aListener);
|
||||
listenerL.add(aListener);
|
||||
}
|
||||
|
||||
public void removeActionListener(ActionListener aListener)
|
||||
{
|
||||
myListeners.remove(aListener);
|
||||
listenerL.remove(aListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,7 +67,7 @@ public class BooleanCellEditor extends AbstractCellEditor implements ActionListe
|
||||
fireEditingStopped();
|
||||
|
||||
aEvent = new ActionEvent(this, aEvent.getID(), "BooleanCell edited.");
|
||||
for (ActionListener aListener : myListeners)
|
||||
for (ActionListener aListener : listenerL)
|
||||
aListener.actionPerformed(aEvent);
|
||||
}
|
||||
|
||||
@@ -60,7 +77,7 @@ public class BooleanCellEditor extends AbstractCellEditor implements ActionListe
|
||||
// Update our checkbox with the appropriate state
|
||||
refCheckBox.removeActionListener(this);
|
||||
if (value instanceof Boolean)
|
||||
refCheckBox.setSelected((Boolean)value);
|
||||
refCheckBox.setSelected((Boolean) value);
|
||||
refCheckBox.addActionListener(this);
|
||||
|
||||
return refCheckBox;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user