From 278341e650a27404c785b485fa53ae32e8befcc1 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 15:59:31 +0300 Subject: [PATCH 1/9] Add CI validation for Java 25 markdown doc style --- .../scripts/validate-java25-markdown-docs.sh | 45 +++++++++++++++++++ .github/workflows/pr.yml | 5 +++ 2 files changed, 50 insertions(+) create mode 100755 .github/scripts/validate-java25-markdown-docs.sh diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh new file mode 100755 index 0000000000..a29b1e8ba0 --- /dev/null +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +set -euo pipefail + +BASE_SHA="${DOCSTYLE_BASE_SHA:-}" +HEAD_SHA="${DOCSTYLE_HEAD_SHA:-HEAD}" + +if [ -z "$BASE_SHA" ]; then + if git rev-parse HEAD^ >/dev/null 2>&1; then + BASE_SHA="HEAD^" + else + echo "Unable to determine base commit. Set DOCSTYLE_BASE_SHA." >&2 + exit 1 + fi +fi + +TARGET_DIRS=("CodenameOne" "Ports/CLDC11") + +echo "Validating Java 25 markdown docs style in ${TARGET_DIRS[*]} between ${BASE_SHA}..${HEAD_SHA}" + +package_violations=$(git diff --name-status --diff-filter=AR "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" | awk '$2 ~ /package\.html$/ {print $0}') + +comment_violations=$(git diff -U0 "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" -- '*.java' | awk ' + /^\+\+\+/ { next } + /^\+/ && $0 ~ /^\+[[:space:]]*\/\*\*/ { print } +') + +failed=0 + +if [ -n "$package_violations" ]; then + failed=1 + echo "ERROR: package.html files were added or renamed into scope. Use package-info.java with markdown doc comments instead:" >&2 + echo "$package_violations" >&2 +fi + +if [ -n "$comment_violations" ]; then + failed=1 + echo "ERROR: Classic Javadoc block comments (/**) were added in Java files. Use Java 25 markdown docs with /// instead:" >&2 + echo "$comment_violations" >&2 +fi + +if [ "$failed" -ne 0 ]; then + exit 1 +fi + +echo "Validation passed: no new /** JavaDoc blocks or package.html files were introduced." diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index eeb5d789e7..fd03ed1987 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -53,6 +53,11 @@ jobs: steps: - uses: actions/checkout@v1 + - name: Validate Java 25 markdown docs style (CodenameOne + CLDC11) + run: ./.github/scripts/validate-java25-markdown-docs.sh + env: + DOCSTYLE_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} + DOCSTYLE_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - name: Set up Java run: | if [ "${{ matrix.java-version }}" = "8" ]; then From 06597a8b1ba316161ca31c2712086ade9577e5e2 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 16:47:21 +0300 Subject: [PATCH 2/9] Make markdown doc validation script repo-root aware --- .../scripts/validate-java25-markdown-docs.sh | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh index a29b1e8ba0..2019fda163 100755 --- a/.github/scripts/validate-java25-markdown-docs.sh +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -1,11 +1,19 @@ #!/usr/bin/env bash set -euo pipefail +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + +if ! git -C "${REPO_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then + echo "Unable to locate a git working tree at ${REPO_ROOT}" >&2 + exit 1 +fi + BASE_SHA="${DOCSTYLE_BASE_SHA:-}" HEAD_SHA="${DOCSTYLE_HEAD_SHA:-HEAD}" if [ -z "$BASE_SHA" ]; then - if git rev-parse HEAD^ >/dev/null 2>&1; then + if git -C "${REPO_ROOT}" rev-parse HEAD^ >/dev/null 2>&1; then BASE_SHA="HEAD^" else echo "Unable to determine base commit. Set DOCSTYLE_BASE_SHA." >&2 @@ -15,11 +23,27 @@ fi TARGET_DIRS=("CodenameOne" "Ports/CLDC11") +if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1; then + echo "Base commit ${BASE_SHA} is not available locally. Attempting to fetch it." >&2 + git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${BASE_SHA}" >/dev/null 2>&1 || true +fi + +if ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then + echo "Head commit ${HEAD_SHA} is not available locally. Attempting to fetch it." >&2 + git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${HEAD_SHA}" >/dev/null 2>&1 || true +fi + +if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1 || \ + ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then + echo "Unable to resolve commit range ${BASE_SHA}..${HEAD_SHA}." >&2 + exit 1 +fi + echo "Validating Java 25 markdown docs style in ${TARGET_DIRS[*]} between ${BASE_SHA}..${HEAD_SHA}" -package_violations=$(git diff --name-status --diff-filter=AR "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" | awk '$2 ~ /package\.html$/ {print $0}') +package_violations=$(git -C "${REPO_ROOT}" diff --name-status --diff-filter=AR "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" | awk '$2 ~ /package\.html$/ {print $0}') -comment_violations=$(git diff -U0 "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" -- '*.java' | awk ' +comment_violations=$(git -C "${REPO_ROOT}" diff -U0 "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" -- '*.java' | awk ' /^\+\+\+/ { next } /^\+/ && $0 ~ /^\+[[:space:]]*\/\*\*/ { print } ') From 99736160953898ef5f8bd81106db731a7e4cccca Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:00:30 +0300 Subject: [PATCH 3/9] Improve git root detection in docs validation script --- .../scripts/validate-java25-markdown-docs.sh | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh index 2019fda163..6d4378b665 100755 --- a/.github/scripts/validate-java25-markdown-docs.sh +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -2,10 +2,23 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" +REPO_ROOT="" + +if git rev-parse --show-toplevel >/dev/null 2>&1; then + REPO_ROOT="$(git rev-parse --show-toplevel)" +elif git -C "${SCRIPT_DIR}" rev-parse --show-toplevel >/dev/null 2>&1; then + REPO_ROOT="$(git -C "${SCRIPT_DIR}" rev-parse --show-toplevel)" +elif [ -n "${GITHUB_WORKSPACE:-}" ] && git -C "${GITHUB_WORKSPACE}" rev-parse --show-toplevel >/dev/null 2>&1; then + REPO_ROOT="$(git -C "${GITHUB_WORKSPACE}" rev-parse --show-toplevel)" +else + CANDIDATE_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" + if [ -d "${CANDIDATE_ROOT}/.git" ] || [ -f "${CANDIDATE_ROOT}/.git" ]; then + REPO_ROOT="${CANDIDATE_ROOT}" + fi +fi -if ! git -C "${REPO_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then - echo "Unable to locate a git working tree at ${REPO_ROOT}" >&2 +if [ -z "${REPO_ROOT}" ] || ! git -C "${REPO_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then + echo "Unable to locate a git working tree. Script dir=${SCRIPT_DIR} GITHUB_WORKSPACE=${GITHUB_WORKSPACE:-}." >&2 exit 1 fi From b8ac358c6ab7bc400b8aa1081862465709635d01 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:13:23 +0300 Subject: [PATCH 4/9] Add GitHub API fallback for markdown docs validation --- .../scripts/validate-java25-markdown-docs.sh | 90 ++++++++++++++----- .github/workflows/pr.yml | 1 + 2 files changed, 71 insertions(+), 20 deletions(-) diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh index 6d4378b665..11355920e7 100755 --- a/.github/scripts/validate-java25-markdown-docs.sh +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -3,6 +3,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="" +HAS_GIT_REPO=0 if git rev-parse --show-toplevel >/dev/null 2>&1; then REPO_ROOT="$(git rev-parse --show-toplevel)" @@ -17,9 +18,8 @@ else fi fi -if [ -z "${REPO_ROOT}" ] || ! git -C "${REPO_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then - echo "Unable to locate a git working tree. Script dir=${SCRIPT_DIR} GITHUB_WORKSPACE=${GITHUB_WORKSPACE:-}." >&2 - exit 1 +if [ -n "${REPO_ROOT}" ] && git -C "${REPO_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then + HAS_GIT_REPO=1 fi BASE_SHA="${DOCSTYLE_BASE_SHA:-}" @@ -36,30 +36,80 @@ fi TARGET_DIRS=("CodenameOne" "Ports/CLDC11") -if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1; then - echo "Base commit ${BASE_SHA} is not available locally. Attempting to fetch it." >&2 - git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${BASE_SHA}" >/dev/null 2>&1 || true -fi +if [ "${HAS_GIT_REPO}" -eq 1 ]; then + if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1; then + echo "Base commit ${BASE_SHA} is not available locally. Attempting to fetch it." >&2 + git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${BASE_SHA}" >/dev/null 2>&1 || true + fi -if ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then - echo "Head commit ${HEAD_SHA} is not available locally. Attempting to fetch it." >&2 - git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${HEAD_SHA}" >/dev/null 2>&1 || true -fi + if ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then + echo "Head commit ${HEAD_SHA} is not available locally. Attempting to fetch it." >&2 + git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${HEAD_SHA}" >/dev/null 2>&1 || true + fi -if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1 || \ - ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then - echo "Unable to resolve commit range ${BASE_SHA}..${HEAD_SHA}." >&2 - exit 1 + if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1 || \ + ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then + echo "Unable to resolve commit range ${BASE_SHA}..${HEAD_SHA} in local git repo." >&2 + HAS_GIT_REPO=0 + fi fi echo "Validating Java 25 markdown docs style in ${TARGET_DIRS[*]} between ${BASE_SHA}..${HEAD_SHA}" -package_violations=$(git -C "${REPO_ROOT}" diff --name-status --diff-filter=AR "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" | awk '$2 ~ /package\.html$/ {print $0}') +package_violations="" +comment_violations="" -comment_violations=$(git -C "${REPO_ROOT}" diff -U0 "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" -- '*.java' | awk ' - /^\+\+\+/ { next } - /^\+/ && $0 ~ /^\+[[:space:]]*\/\*\*/ { print } -') +if [ "${HAS_GIT_REPO}" -eq 1 ]; then + package_violations=$(git -C "${REPO_ROOT}" diff --name-status --diff-filter=AR "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" | awk '$2 ~ /package\.html$/ {print $0}') + + comment_violations=$(git -C "${REPO_ROOT}" diff -U0 "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" -- '*.java' | awk ' + /^\+\+\+/ { next } + /^\+/ && $0 ~ /^\+[[:space:]]*\/\*\*/ { print } + ') +else + if [ -z "${GITHUB_TOKEN:-}" ] || [ -z "${GITHUB_REPOSITORY:-}" ]; then + echo "No local git repo available and missing GITHUB_TOKEN/GITHUB_REPOSITORY for API fallback." >&2 + exit 1 + fi + + compare_url="https://api.github.com/repos/${GITHUB_REPOSITORY}/compare/${BASE_SHA}...${HEAD_SHA}" + compare_json="$(curl -fsSL -H "Authorization: Bearer ${GITHUB_TOKEN}" -H "Accept: application/vnd.github+json" "${compare_url}")" + + parsed_output="$(printf '%s' "${compare_json}" | python3 - <<'PY' +import json +import re +import sys + +data = json.load(sys.stdin) +targets = ("CodenameOne/", "Ports/CLDC11/") +package_hits = [] +comment_hits = [] + +for f in data.get("files", []): + status = f.get("status", "") + filename = f.get("filename", "") + if filename.startswith(targets) and filename.endswith("package.html") and status in ("added", "renamed"): + package_hits.append(f"{status}\t{filename}") + if filename.startswith(targets) and filename.endswith(".java"): + patch = f.get("patch") or "" + for line in patch.splitlines(): + if line.startswith("+++") or not line.startswith("+"): + continue + if re.match(r"^\+\s*/\*\*", line): + comment_hits.append(f"{filename}: {line}") + +print("PACKAGE_START") +print("\n".join(package_hits)) +print("PACKAGE_END") +print("COMMENT_START") +print("\n".join(comment_hits)) +print("COMMENT_END") +PY +)" + + package_violations="$(printf '%s\n' "${parsed_output}" | sed -n '/^PACKAGE_START$/,/^PACKAGE_END$/p' | sed '1d;$d')" + comment_violations="$(printf '%s\n' "${parsed_output}" | sed -n '/^COMMENT_START$/,/^COMMENT_END$/p' | sed '1d;$d')" +fi failed=0 diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index fd03ed1987..0659fb279f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -58,6 +58,7 @@ jobs: env: DOCSTYLE_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} DOCSTYLE_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} + GITHUB_TOKEN: ${{ github.token }} - name: Set up Java run: | if [ "${{ matrix.java-version }}" = "8" ]; then From 359679b934832ba346c69cd05c5e678c0fe1dc59 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 17:19:35 +0300 Subject: [PATCH 5/9] Simplify markdown docs validation to full-tree grep --- .../scripts/validate-java25-markdown-docs.sh | 131 +----------------- .github/workflows/pr.yml | 4 - 2 files changed, 4 insertions(+), 131 deletions(-) diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh index 11355920e7..6ec2121780 100755 --- a/.github/scripts/validate-java25-markdown-docs.sh +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -1,132 +1,9 @@ #!/usr/bin/env bash set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -REPO_ROOT="" -HAS_GIT_REPO=0 - -if git rev-parse --show-toplevel >/dev/null 2>&1; then - REPO_ROOT="$(git rev-parse --show-toplevel)" -elif git -C "${SCRIPT_DIR}" rev-parse --show-toplevel >/dev/null 2>&1; then - REPO_ROOT="$(git -C "${SCRIPT_DIR}" rev-parse --show-toplevel)" -elif [ -n "${GITHUB_WORKSPACE:-}" ] && git -C "${GITHUB_WORKSPACE}" rev-parse --show-toplevel >/dev/null 2>&1; then - REPO_ROOT="$(git -C "${GITHUB_WORKSPACE}" rev-parse --show-toplevel)" -else - CANDIDATE_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" - if [ -d "${CANDIDATE_ROOT}/.git" ] || [ -f "${CANDIDATE_ROOT}/.git" ]; then - REPO_ROOT="${CANDIDATE_ROOT}" - fi -fi - -if [ -n "${REPO_ROOT}" ] && git -C "${REPO_ROOT}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then - HAS_GIT_REPO=1 -fi - -BASE_SHA="${DOCSTYLE_BASE_SHA:-}" -HEAD_SHA="${DOCSTYLE_HEAD_SHA:-HEAD}" - -if [ -z "$BASE_SHA" ]; then - if git -C "${REPO_ROOT}" rev-parse HEAD^ >/dev/null 2>&1; then - BASE_SHA="HEAD^" - else - echo "Unable to determine base commit. Set DOCSTYLE_BASE_SHA." >&2 - exit 1 - fi -fi - -TARGET_DIRS=("CodenameOne" "Ports/CLDC11") - -if [ "${HAS_GIT_REPO}" -eq 1 ]; then - if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1; then - echo "Base commit ${BASE_SHA} is not available locally. Attempting to fetch it." >&2 - git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${BASE_SHA}" >/dev/null 2>&1 || true - fi - - if ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then - echo "Head commit ${HEAD_SHA} is not available locally. Attempting to fetch it." >&2 - git -C "${REPO_ROOT}" fetch --no-tags --depth=200 origin "${HEAD_SHA}" >/dev/null 2>&1 || true - fi - - if ! git -C "${REPO_ROOT}" cat-file -e "${BASE_SHA}^{commit}" >/dev/null 2>&1 || \ - ! git -C "${REPO_ROOT}" cat-file -e "${HEAD_SHA}^{commit}" >/dev/null 2>&1; then - echo "Unable to resolve commit range ${BASE_SHA}..${HEAD_SHA} in local git repo." >&2 - HAS_GIT_REPO=0 - fi -fi - -echo "Validating Java 25 markdown docs style in ${TARGET_DIRS[*]} between ${BASE_SHA}..${HEAD_SHA}" - -package_violations="" -comment_violations="" - -if [ "${HAS_GIT_REPO}" -eq 1 ]; then - package_violations=$(git -C "${REPO_ROOT}" diff --name-status --diff-filter=AR "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" | awk '$2 ~ /package\.html$/ {print $0}') - - comment_violations=$(git -C "${REPO_ROOT}" diff -U0 "$BASE_SHA" "$HEAD_SHA" -- "${TARGET_DIRS[@]}" -- '*.java' | awk ' - /^\+\+\+/ { next } - /^\+/ && $0 ~ /^\+[[:space:]]*\/\*\*/ { print } - ') -else - if [ -z "${GITHUB_TOKEN:-}" ] || [ -z "${GITHUB_REPOSITORY:-}" ]; then - echo "No local git repo available and missing GITHUB_TOKEN/GITHUB_REPOSITORY for API fallback." >&2 - exit 1 - fi - - compare_url="https://api.github.com/repos/${GITHUB_REPOSITORY}/compare/${BASE_SHA}...${HEAD_SHA}" - compare_json="$(curl -fsSL -H "Authorization: Bearer ${GITHUB_TOKEN}" -H "Accept: application/vnd.github+json" "${compare_url}")" - - parsed_output="$(printf '%s' "${compare_json}" | python3 - <<'PY' -import json -import re -import sys - -data = json.load(sys.stdin) -targets = ("CodenameOne/", "Ports/CLDC11/") -package_hits = [] -comment_hits = [] - -for f in data.get("files", []): - status = f.get("status", "") - filename = f.get("filename", "") - if filename.startswith(targets) and filename.endswith("package.html") and status in ("added", "renamed"): - package_hits.append(f"{status}\t{filename}") - if filename.startswith(targets) and filename.endswith(".java"): - patch = f.get("patch") or "" - for line in patch.splitlines(): - if line.startswith("+++") or not line.startswith("+"): - continue - if re.match(r"^\+\s*/\*\*", line): - comment_hits.append(f"{filename}: {line}") - -print("PACKAGE_START") -print("\n".join(package_hits)) -print("PACKAGE_END") -print("COMMENT_START") -print("\n".join(comment_hits)) -print("COMMENT_END") -PY -)" - - package_violations="$(printf '%s\n' "${parsed_output}" | sed -n '/^PACKAGE_START$/,/^PACKAGE_END$/p' | sed '1d;$d')" - comment_violations="$(printf '%s\n' "${parsed_output}" | sed -n '/^COMMENT_START$/,/^COMMENT_END$/p' | sed '1d;$d')" -fi - failed=0 -if [ -n "$package_violations" ]; then - failed=1 - echo "ERROR: package.html files were added or renamed into scope. Use package-info.java with markdown doc comments instead:" >&2 - echo "$package_violations" >&2 -fi - -if [ -n "$comment_violations" ]; then - failed=1 - echo "ERROR: Classic Javadoc block comments (/**) were added in Java files. Use Java 25 markdown docs with /// instead:" >&2 - echo "$comment_violations" >&2 -fi - -if [ "$failed" -ne 0 ]; then - exit 1 -fi +rg -n '/\*\*' CodenameOne Ports/CLDC11 && { echo 'ERROR: Found classic Javadoc markers (/**). Use /// markdown comments.' >&2; failed=1; } || true +rg --files CodenameOne Ports/CLDC11 | rg '/package\.html$' && { echo 'ERROR: Found package.html files. Use package-info.java with /// markdown comments.' >&2; failed=1; } || true -echo "Validation passed: no new /** JavaDoc blocks or package.html files were introduced." +[ "$failed" -eq 0 ] && echo 'Validation passed: no /** markers and no package.html files found in CodenameOne or Ports/CLDC11.' +exit "$failed" diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 0659fb279f..7b88b9aa25 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -55,10 +55,6 @@ jobs: - uses: actions/checkout@v1 - name: Validate Java 25 markdown docs style (CodenameOne + CLDC11) run: ./.github/scripts/validate-java25-markdown-docs.sh - env: - DOCSTYLE_BASE_SHA: ${{ github.event.pull_request.base.sha || github.event.before }} - DOCSTYLE_HEAD_SHA: ${{ github.event.pull_request.head.sha || github.sha }} - GITHUB_TOKEN: ${{ github.token }} - name: Set up Java run: | if [ "${{ matrix.java-version }}" = "8" ]; then From 16ed08663b8c9f838efc080a68aab6ef2afd08c5 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:17:20 +0300 Subject: [PATCH 6/9] Make markdown docs validator run from repo root --- .github/scripts/validate-java25-markdown-docs.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh index 6ec2121780..df6896868a 100755 --- a/.github/scripts/validate-java25-markdown-docs.sh +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -1,9 +1,11 @@ #!/usr/bin/env bash set -euo pipefail +cd "$(cd "$(dirname "$0")/../.." && pwd)" +[ -d CodenameOne ] && [ -d Ports/CLDC11 ] || { echo 'ERROR: Expected CodenameOne and Ports/CLDC11 directories.' >&2; exit 1; } failed=0 -rg -n '/\*\*' CodenameOne Ports/CLDC11 && { echo 'ERROR: Found classic Javadoc markers (/**). Use /// markdown comments.' >&2; failed=1; } || true -rg --files CodenameOne Ports/CLDC11 | rg '/package\.html$' && { echo 'ERROR: Found package.html files. Use package-info.java with /// markdown comments.' >&2; failed=1; } || true +if rg -n '/\*\*' CodenameOne Ports/CLDC11; then echo 'ERROR: Found classic Javadoc markers (/**). Use /// markdown comments.' >&2; failed=1; fi +if rg --files CodenameOne Ports/CLDC11 | rg '/package\.html$'; then echo 'ERROR: Found package.html files. Use package-info.java with /// markdown comments.' >&2; failed=1; fi [ "$failed" -eq 0 ] && echo 'Validation passed: no /** markers and no package.html files found in CodenameOne or Ports/CLDC11.' exit "$failed" From 17e15826e4af531daab2459b1093a3593c6219f3 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:06:56 +0300 Subject: [PATCH 7/9] Fail docs validator on missing tools and wrong cwd --- .github/scripts/validate-java25-markdown-docs.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh index df6896868a..3a601fb7dc 100755 --- a/.github/scripts/validate-java25-markdown-docs.sh +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -4,8 +4,16 @@ cd "$(cd "$(dirname "$0")/../.." && pwd)" [ -d CodenameOne ] && [ -d Ports/CLDC11 ] || { echo 'ERROR: Expected CodenameOne and Ports/CLDC11 directories.' >&2; exit 1; } failed=0 -if rg -n '/\*\*' CodenameOne Ports/CLDC11; then echo 'ERROR: Found classic Javadoc markers (/**). Use /// markdown comments.' >&2; failed=1; fi -if rg --files CodenameOne Ports/CLDC11 | rg '/package\.html$'; then echo 'ERROR: Found package.html files. Use package-info.java with /// markdown comments.' >&2; failed=1; fi +javadoc_hits="$(mktemp)" && package_hits="$(mktemp)" +if find CodenameOne Ports/CLDC11 -type f -name '*.java' -print0 | xargs -0 grep -n -- '/\*\*' >"$javadoc_hits"; then + cat "$javadoc_hits"; echo 'ERROR: Found classic Javadoc markers (/**). Use /// markdown comments.' >&2; failed=1 +else + grep_status=$? + [ "$grep_status" -eq 1 ] || { echo 'ERROR: Failed while scanning for /** markers.' >&2; exit "$grep_status"; } +fi +find CodenameOne Ports/CLDC11 -type f -name 'package.html' >"$package_hits" +if [ -s "$package_hits" ]; then cat "$package_hits"; echo 'ERROR: Found package.html files. Use package-info.java with /// markdown comments.' >&2; failed=1; fi [ "$failed" -eq 0 ] && echo 'Validation passed: no /** markers and no package.html files found in CodenameOne or Ports/CLDC11.' +rm -f "$javadoc_hits" "$package_hits" exit "$failed" From 728457917e029b00b420e60a54ee3179cfab567c Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:44:28 +0300 Subject: [PATCH 8/9] Remove legacy package.html and remaining /** doc blocks --- .../scripts/validate-java25-markdown-docs.sh | 2 +- .../src/com/codename1/ads/package.html | 18 - .../src/com/codename1/analytics/package.html | 16 - .../annotations/DisableDebugInfo.java | 4 +- ...DisableNullChecksAndArrayBoundsChecks.java | 4 +- .../src/com/codename1/background/package.html | 12 - .../src/com/codename1/capture/package.html | 16 - .../com/codename1/charts/compat/package.html | 6 - .../com/codename1/charts/models/package.html | 6 - .../src/com/codename1/charts/package.html | 99 --- .../codename1/charts/renderers/package.html | 6 - .../com/codename1/charts/util/package.html | 6 - .../com/codename1/charts/views/package.html | 6 - .../src/com/codename1/codescan/package.html | 13 - .../src/com/codename1/components/package.html | 12 - .../src/com/codename1/contacts/package.html | 29 - CodenameOne/src/com/codename1/db/package.html | 60 -- .../src/com/codename1/facebook/package.html | 12 - .../com/codename1/facebook/ui/package.html | 11 - .../codename1/impl/JdkApiRewriteHelper.java | 4 +- .../src/com/codename1/impl/package.html | 19 - .../src/com/codename1/io/gzip/package.html | 11 - CodenameOne/src/com/codename1/io/package.html | 717 ----------------- .../src/com/codename1/io/rest/package.html | 13 - .../com/codename1/io/services/package.html | 11 - .../src/com/codename1/io/tar/package.html | 14 - .../src/com/codename1/javascript/package.html | 730 ------------------ .../src/com/codename1/l10n/package.html | 37 - .../src/com/codename1/location/package.html | 33 - .../com/codename1/maps/layers/package.html | 16 - .../src/com/codename1/maps/package.html | 21 - .../com/codename1/maps/providers/package.html | 16 - .../src/com/codename1/media/Media.java | 13 +- .../src/com/codename1/media/package.html | 37 - .../src/com/codename1/messaging/package.html | 26 - .../com/codename1/notifications/package.html | 111 --- .../src/com/codename1/payment/package.html | 12 - .../src/com/codename1/processing/package.html | 122 --- .../src/com/codename1/properties/package.html | 12 - .../src/com/codename1/push/package.html | 11 - .../src/com/codename1/share/package.html | 11 - .../src/com/codename1/social/package.html | 11 - .../src/com/codename1/system/package.html | 96 --- .../src/com/codename1/testing/package.html | 11 - .../com/codename1/ui/animations/package.html | 18 - .../src/com/codename1/ui/events/package.html | 18 - .../src/com/codename1/ui/geom/package.html | 12 - .../src/com/codename1/ui/html/package.html | 20 - .../com/codename1/ui/layouts/GroupLayout.java | 4 +- .../src/com/codename1/ui/layouts/package.html | 81 -- .../src/com/codename1/ui/list/package.html | 31 - CodenameOne/src/com/codename1/ui/package.html | 459 ----------- .../src/com/codename1/ui/painter/package.html | 21 - .../src/com/codename1/ui/plaf/package.html | 25 - .../src/com/codename1/ui/scene/package.html | 17 - .../src/com/codename1/ui/spinner/package.html | 17 - .../src/com/codename1/ui/table/package.html | 16 - .../src/com/codename1/ui/tree/package.html | 16 - .../src/com/codename1/ui/util/package.html | 17 - .../com/codename1/ui/validation/package.html | 12 - .../src/com/codename1/util/Base64.java | 39 +- .../src/com/codename1/util/package.html | 16 - .../src/com/codename1/util/regex/package.html | 16 - .../src/com/codename1/xml/package.html | 18 - 64 files changed, 35 insertions(+), 3291 deletions(-) delete mode 100644 CodenameOne/src/com/codename1/ads/package.html delete mode 100644 CodenameOne/src/com/codename1/analytics/package.html delete mode 100644 CodenameOne/src/com/codename1/background/package.html delete mode 100644 CodenameOne/src/com/codename1/capture/package.html delete mode 100644 CodenameOne/src/com/codename1/charts/compat/package.html delete mode 100644 CodenameOne/src/com/codename1/charts/models/package.html delete mode 100644 CodenameOne/src/com/codename1/charts/package.html delete mode 100644 CodenameOne/src/com/codename1/charts/renderers/package.html delete mode 100644 CodenameOne/src/com/codename1/charts/util/package.html delete mode 100644 CodenameOne/src/com/codename1/charts/views/package.html delete mode 100644 CodenameOne/src/com/codename1/codescan/package.html delete mode 100644 CodenameOne/src/com/codename1/components/package.html delete mode 100644 CodenameOne/src/com/codename1/contacts/package.html delete mode 100644 CodenameOne/src/com/codename1/db/package.html delete mode 100644 CodenameOne/src/com/codename1/facebook/package.html delete mode 100644 CodenameOne/src/com/codename1/facebook/ui/package.html delete mode 100644 CodenameOne/src/com/codename1/impl/package.html delete mode 100644 CodenameOne/src/com/codename1/io/gzip/package.html delete mode 100644 CodenameOne/src/com/codename1/io/package.html delete mode 100644 CodenameOne/src/com/codename1/io/rest/package.html delete mode 100644 CodenameOne/src/com/codename1/io/services/package.html delete mode 100644 CodenameOne/src/com/codename1/io/tar/package.html delete mode 100644 CodenameOne/src/com/codename1/javascript/package.html delete mode 100644 CodenameOne/src/com/codename1/l10n/package.html delete mode 100644 CodenameOne/src/com/codename1/location/package.html delete mode 100644 CodenameOne/src/com/codename1/maps/layers/package.html delete mode 100644 CodenameOne/src/com/codename1/maps/package.html delete mode 100644 CodenameOne/src/com/codename1/maps/providers/package.html delete mode 100644 CodenameOne/src/com/codename1/media/package.html delete mode 100644 CodenameOne/src/com/codename1/messaging/package.html delete mode 100644 CodenameOne/src/com/codename1/notifications/package.html delete mode 100644 CodenameOne/src/com/codename1/payment/package.html delete mode 100644 CodenameOne/src/com/codename1/processing/package.html delete mode 100644 CodenameOne/src/com/codename1/properties/package.html delete mode 100644 CodenameOne/src/com/codename1/push/package.html delete mode 100644 CodenameOne/src/com/codename1/share/package.html delete mode 100644 CodenameOne/src/com/codename1/social/package.html delete mode 100644 CodenameOne/src/com/codename1/system/package.html delete mode 100644 CodenameOne/src/com/codename1/testing/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/animations/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/events/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/geom/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/html/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/layouts/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/list/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/painter/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/plaf/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/scene/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/spinner/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/table/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/tree/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/util/package.html delete mode 100644 CodenameOne/src/com/codename1/ui/validation/package.html delete mode 100644 CodenameOne/src/com/codename1/util/package.html delete mode 100644 CodenameOne/src/com/codename1/util/regex/package.html delete mode 100644 CodenameOne/src/com/codename1/xml/package.html diff --git a/.github/scripts/validate-java25-markdown-docs.sh b/.github/scripts/validate-java25-markdown-docs.sh index 3a601fb7dc..f6869425f7 100755 --- a/.github/scripts/validate-java25-markdown-docs.sh +++ b/.github/scripts/validate-java25-markdown-docs.sh @@ -5,7 +5,7 @@ cd "$(cd "$(dirname "$0")/../.." && pwd)" failed=0 javadoc_hits="$(mktemp)" && package_hits="$(mktemp)" -if find CodenameOne Ports/CLDC11 -type f -name '*.java' -print0 | xargs -0 grep -n -- '/\*\*' >"$javadoc_hits"; then +if grep -R -nE --include='*.java' '^[[:space:]]*/\*\*' CodenameOne Ports/CLDC11 >"$javadoc_hits"; then cat "$javadoc_hits"; echo 'ERROR: Found classic Javadoc markers (/**). Use /// markdown comments.' >&2; failed=1 else grep_status=$? diff --git a/CodenameOne/src/com/codename1/ads/package.html b/CodenameOne/src/com/codename1/ads/package.html deleted file mode 100644 index 6c23f912bf..0000000000 --- a/CodenameOne/src/com/codename1/ads/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - -

- A legacy banner Ads API. This has been replaced by more modern approaches mainly thru cn1libs. -

-

- Currently inner-active ads Network is supported - please refer to - inner-active - for more information -

- - diff --git a/CodenameOne/src/com/codename1/analytics/package.html b/CodenameOne/src/com/codename1/analytics/package.html deleted file mode 100644 index ce9b53d648..0000000000 --- a/CodenameOne/src/com/codename1/analytics/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - -

- The analytics API allows tracking your mobile application usage in the field to give you real-time - data on how your application is used. This API currently delegates to the Google analytics service. -

-

- Notice that analytics is automatically added GUI applications created by the old GUI builder, you only need - to enable Analytics specifically by invoking the init method and the pages will be logged automatically. -

- - diff --git a/CodenameOne/src/com/codename1/annotations/DisableDebugInfo.java b/CodenameOne/src/com/codename1/annotations/DisableDebugInfo.java index 23a11cd503..5c98e2b643 100644 --- a/CodenameOne/src/com/codename1/annotations/DisableDebugInfo.java +++ b/CodenameOne/src/com/codename1/annotations/DisableDebugInfo.java @@ -5,9 +5,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** - * Marks a method so ParparVM omits emitted debug line information. - */ +/// Marks a method so ParparVM omits emitted debug line information. @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface DisableDebugInfo { diff --git a/CodenameOne/src/com/codename1/annotations/DisableNullChecksAndArrayBoundsChecks.java b/CodenameOne/src/com/codename1/annotations/DisableNullChecksAndArrayBoundsChecks.java index 4c38e4de6e..ce8bd57975 100644 --- a/CodenameOne/src/com/codename1/annotations/DisableNullChecksAndArrayBoundsChecks.java +++ b/CodenameOne/src/com/codename1/annotations/DisableNullChecksAndArrayBoundsChecks.java @@ -5,9 +5,7 @@ import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; -/** - * Marks a method so ParparVM omits emitted null and array bounds checks. - */ +/// Marks a method so ParparVM omits emitted null and array bounds checks. @Retention(RetentionPolicy.CLASS) @Target(ElementType.METHOD) public @interface DisableNullChecksAndArrayBoundsChecks { diff --git a/CodenameOne/src/com/codename1/background/package.html b/CodenameOne/src/com/codename1/background/package.html deleted file mode 100644 index e54ff917ea..0000000000 --- a/CodenameOne/src/com/codename1/background/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -

Background fetch is a mechanism whereby an application is granted permission by the operating system to update its - data periodically. At times of the native platform's choosing, an app that supports background fetch will be started - up (in the background), and its {@link com.codename1.background.BackgroundFetch#performBackgroundFetch(long, - com.codename1.util.Callback) } method will be called.

- - diff --git a/CodenameOne/src/com/codename1/capture/package.html b/CodenameOne/src/com/codename1/capture/package.html deleted file mode 100644 index d3eb8f9c8f..0000000000 --- a/CodenameOne/src/com/codename1/capture/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - -

- Package for capturing photos, audio or video from the camera/microphone. -

-

- The code below demonstrates capturing and playing back audio files using this API: -

- -Captured recordings in the demo - - diff --git a/CodenameOne/src/com/codename1/charts/compat/package.html b/CodenameOne/src/com/codename1/charts/compat/package.html deleted file mode 100644 index 9290c7f106..0000000000 --- a/CodenameOne/src/com/codename1/charts/compat/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -Compat - -This package contains compatibility classes for internal use - - \ No newline at end of file diff --git a/CodenameOne/src/com/codename1/charts/models/package.html b/CodenameOne/src/com/codename1/charts/models/package.html deleted file mode 100644 index 6135d29c79..0000000000 --- a/CodenameOne/src/com/codename1/charts/models/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Provides the classes that handle the data values (data model) to be used by displaying the charts. - - \ No newline at end of file diff --git a/CodenameOne/src/com/codename1/charts/package.html b/CodenameOne/src/com/codename1/charts/package.html deleted file mode 100644 index 9a25d99bd4..0000000000 --- a/CodenameOne/src/com/codename1/charts/package.html +++ /dev/null @@ -1,99 +0,0 @@ - -Charts Support - -

The main ChartComponent Package

-

- The charts package enables Codename One developers to add charts and - visualizations to their apps without having to include external libraries or embedding web views. - We also wanted to harness the new features in the graphics pipeline to maximize performance.

- -

Device Support

-

- Since the charts package makes use of 2D transformations and shapes, it requires some - of the graphics features that are not yet available on all platforms. Currently the following - platforms are supported: -

-
    -
  1. Simulator
  2. -
  3. Android
  4. -
  5. iOS
  6. -
- -

Features

-
    -
  1. Built-in support for many common types of charts including bar charts, - line charts, stacked charts, scatter charts, pie charts and more. -
  2. -
  3. Pinch Zoom - The {@link com.codename1.charts,ChartComponent} - class includes optional pinch zoom support. -
  4. -
  5. Panning Support - The - {@link com.codename1.charts,ChartComponent} class includes optional support for panning. -
  6. -
- -

Chart Types

-

- The com.codename1.charts package includes models and renderers for many - different types of charts. It is also extensible so that you can add your own chart types if required. - The following screen shots demonstrate a small sampling of the types of charts that can be - created. -

-Line Charts -Cubic Line Charts - -Bar Charts -Stacked Bar Charts -Range Bar Charts -Pie Charts -Doughnut Charts -Scatter Charts -Dial Charts -Combined Charts -Bubble Charts -Time Charts - - - - - - - - -
- The above screenshots were taken from the - ChartsDemo app. Y - ou can start playing with this app by checking it out from our git repository. -
- -

How to Create A Chart

-

Adding a chart to your app involves four steps:

-
    -
  1. Build the model. You can construct a model (aka data set) for the chart using one of the - existing model classes in the com.codename1.charts.models package. Essentially, this - is just where you add the data that you want to display. -
  2. -
  3. Set up a renderer. You can create a renderer for your chart using one of the - existing renderer classes in the com.codename1.charts.renderers package. The renderer - allows you to specify how the chart should look. E.g. the colors, fonts, styles, to use. -
  4. -
  5. Create the Chart View. Use one of the existing view classes in the - com.codename1.charts.views package. -
  6. -
  7. Create a {@link com.codename1.charts,ChartComponent} . In order to add your - chart to the UI, you need to wrap it in a {@link com.codename1.charts,ChartComponent} object. -
  8. -
- -

You can check out the ChartsDemo - app for specific examples, but here is a high level view of some code that creates a Pie Chart.

- - - -

- The charts package is derived work from the excellent open source - aChartEngine API. -

- - \ No newline at end of file diff --git a/CodenameOne/src/com/codename1/charts/renderers/package.html b/CodenameOne/src/com/codename1/charts/renderers/package.html deleted file mode 100644 index c9db0a454a..0000000000 --- a/CodenameOne/src/com/codename1/charts/renderers/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Provides renderer classes that keep the chart rendering / drawing styles. - - \ No newline at end of file diff --git a/CodenameOne/src/com/codename1/charts/util/package.html b/CodenameOne/src/com/codename1/charts/util/package.html deleted file mode 100644 index da92e91330..0000000000 --- a/CodenameOne/src/com/codename1/charts/util/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Utility classes that provide helper methods used by most of the other packages. - - \ No newline at end of file diff --git a/CodenameOne/src/com/codename1/charts/views/package.html b/CodenameOne/src/com/codename1/charts/views/package.html deleted file mode 100644 index 2c5fbec195..0000000000 --- a/CodenameOne/src/com/codename1/charts/views/package.html +++ /dev/null @@ -1,6 +0,0 @@ - -AChartEngine - -Provides the classes that handle the actual rendering / drawing of the charts, based on the provided model and renderer. - - \ No newline at end of file diff --git a/CodenameOne/src/com/codename1/codescan/package.html b/CodenameOne/src/com/codename1/codescan/package.html deleted file mode 100644 index dc69925353..0000000000 --- a/CodenameOne/src/com/codename1/codescan/package.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - -

Deprecated!!: Please use the cn1-codescan - library instead.

-

- Bar/QR code scanning API, currently based on the zxing implementation -

- - diff --git a/CodenameOne/src/com/codename1/components/package.html b/CodenameOne/src/com/codename1/components/package.html deleted file mode 100644 index 503336afc0..0000000000 --- a/CodenameOne/src/com/codename1/components/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -

- Generic elaborate components that make use of both UI elements and storage. - These are relatively high level components such as RSS reader, IO progress indication etc. -

- - diff --git a/CodenameOne/src/com/codename1/contacts/package.html b/CodenameOne/src/com/codename1/contacts/package.html deleted file mode 100644 index 645ecf3d42..0000000000 --- a/CodenameOne/src/com/codename1/contacts/package.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - -

- Provides access to the contacts list from the device address book -

-

- The contacts API provides us with the means to query the phone�s address book, delete elements from - it and create new entries into it. -

-

- Notice that on some platforms this will prompt the user for permissions and the user might choose not - to grant that permission. To detect whether this is the case you can invoke - {@link com.codename1.Display#isContactsPermissionGranted()} after invoking the contact listing API. - This can help you adapt your error message to the user. -

-

- The sample below demonstrates listing all the contacts within the device with their photos, notice that - this API is very performance sensitive and should be invoked on a separate thread unlike most - Codename One API's: -

- -Contacts with the default photos on the simulator, on device these will use actual user photos when available - - diff --git a/CodenameOne/src/com/codename1/db/package.html b/CodenameOne/src/com/codename1/db/package.html deleted file mode 100644 index 5edef5087e..0000000000 --- a/CodenameOne/src/com/codename1/db/package.html +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - -

SQLite database access API

- -

- Most new devices contain one version of sqlite or another; sqlite is a very lightweight SQL database - designed for embedding into devices. For portability we recommend avoiding SQL altogether since - it is both fragmented between devices (different sqlite versions) and isn't supported on all devices. -

- -

In general SQL seems overly complex for most embedded device programming tasks.

- -

Portability Of SQLite

-

SQLite is supported on iOS, Android, UWP (Universal Windows Platform), RIM, Desktop & JavaScript builds. However, - the JavaScript - version of SQL has been deprecated and isn't supported on all platforms.

-

You will notice that at this time support is still missing from the Windows builds.

-

The biggest issue with SQLite portability is in iOS. The SQLite version for most platforms is - threadsafe and as a result very stable. However, the iOS version is not!

-

This might not seem like a big deal normally, however if you forget to close a connection the GC might - close it for you thus producing a crash. This is such a common occurrence that Codename One logs - a warning when the GC collects a database resource on the simulator.

- -

Using SQLite

-

SQL is pretty powerful and very well suited for common tabular data. The Codename One SQL - API is similar in spirit to JDBC but considerably simpler since many of the abstractions of JDBC - designed for pluggable database architecture make no sense for a local database.

- -

The {@link com.codename1.db.Database} API is a high level abstraction that allows you to open an - arbitrary database file using syntax such as:

- - - -

Some SQLite apps ship with a "ready made" database. We allow you to replace the DB file by using the code:

- - - -

You can then use the {@link com.codename1.io.FileSystemStorage} class to write the content of your - DB file into the path. Notice that it must be a valid SQLite file!

- -

This is very useful for applications that need to synchronize with a central server or applications that - ship with a large database as part of their core product.

- -

Working with a database is pretty trivial, the application logic below can send arbitrary queries to the - database and present the results in a {@link com.codename1.ui.table.Table}. You can probably integrate - this code into your app as a debugging tool:

- - - -Querying the temp demo generated by the SQLDemo application -Issuing a query - - - - diff --git a/CodenameOne/src/com/codename1/facebook/package.html b/CodenameOne/src/com/codename1/facebook/package.html deleted file mode 100644 index eb82f92990..0000000000 --- a/CodenameOne/src/com/codename1/facebook/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -

- Legacy generic implementation of the Facebook API with simplified OAuth integration to allow social sharing. - It is recommended to migrate to the new social package services -

- - diff --git a/CodenameOne/src/com/codename1/facebook/ui/package.html b/CodenameOne/src/com/codename1/facebook/ui/package.html deleted file mode 100644 index 88bff22d7e..0000000000 --- a/CodenameOne/src/com/codename1/facebook/ui/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -

- User interface for integrating with basic Facebook features currently mostly the Like button -

- - diff --git a/CodenameOne/src/com/codename1/impl/JdkApiRewriteHelper.java b/CodenameOne/src/com/codename1/impl/JdkApiRewriteHelper.java index 7a094a7b14..5d72e0d673 100644 --- a/CodenameOne/src/com/codename1/impl/JdkApiRewriteHelper.java +++ b/CodenameOne/src/com/codename1/impl/JdkApiRewriteHelper.java @@ -3,9 +3,7 @@ import com.codename1.util.regex.RE; import com.codename1.util.regex.RESyntaxException; -/** - * Bridge methods used by bytecode rewrite rules for JDK APIs that are risky/unsupported on some targets. - */ +/// Bridge methods used by bytecode rewrite rules for JDK APIs that are risky/unsupported on some targets. public final class JdkApiRewriteHelper { private JdkApiRewriteHelper() { } diff --git a/CodenameOne/src/com/codename1/impl/package.html b/CodenameOne/src/com/codename1/impl/package.html deleted file mode 100644 index bffd778233..0000000000 --- a/CodenameOne/src/com/codename1/impl/package.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - -

- The implementation package should not be used by developers, it is an internal implementation detail - which will break compatibility between major Codename One releases. The purpose of this package is to provide - ISVs, vendors and operators with the ability to customize & enhance Codename One from within without - breaking compatability with existing Codename One applications. -

-

- A vendor extension begins by extending the CodenameOneImplementation class and implementing the abstract - methods within. To use this version of the implementation a user can use the Display class and link - to a vendor JAR that doesn't include any portion of Codename One. -

- - diff --git a/CodenameOne/src/com/codename1/io/gzip/package.html b/CodenameOne/src/com/codename1/io/gzip/package.html deleted file mode 100644 index 9fe777462b..0000000000 --- a/CodenameOne/src/com/codename1/io/gzip/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -

- gzip support based on https://github.com/ymnk/jzlib -

- - diff --git a/CodenameOne/src/com/codename1/io/package.html b/CodenameOne/src/com/codename1/io/package.html deleted file mode 100644 index 36f94291ce..0000000000 --- a/CodenameOne/src/com/codename1/io/package.html +++ /dev/null @@ -1,717 +0,0 @@ - - - - - - -

Networking, Storage, Filesystem & related API's

-

- The IO package includes all of the main features related to storage and networking with the exception - of {@link com.codename1.db SQL} & XML parsing. -

- -

Storage

-

- {@link com.codename1.io.Storage} is accessed via the Storage - class. It is a flat filesystem like interface and contains the ability to list/delete and - write to named storage entries. -

- -

- The {@link com.codename1.io.Storage} API also provides convenient methods to write objects to - {@link com.codename1.io.Storage} and read them from {@link com.codename1.io.Storage} specifically - readObject & writeObject.
- Notice that objects in {@link com.codename1.io.Storage} are deleted when an app is uninstalled but are - retained between application updates. -

- -

- The sample code below demonstrates listing the content of the storage, adding/viewing and - deleting entries within the storage: -

- - - -List of files within the storage -Content of a file added to the storage - -

The Preferences API

- -

- {@link com.codename1.io.Storage} also offers a very simple API in the form of the - {@link com.codename1.io.Preferences} - class. The {@link com.codename1.io.Preferences} class allows developers to store simple variables, strings, - numbers, booleans etc. in storage without writing any storage code. This is a common use case - within applications e.g. you have a server token that you need to store you can store & read it like this: -

- - - -

- This gets somewhat confusing with primitive numbers e.g. if you use - Preferences.set("primitiveLongValue", myLongNumber) then invoke - Preferences.get("primitiveLongValue", 0) you might get an exception!
- This would happen because the value is physically a Long object but you are - trying to get an Integer. The workaround is to remain consistent and use code - like this Preferences.get("primitiveLongValue", (long)0). -

- -

File System

-

- {@link com.codename1.io.FileSystemStorage} provides file system access. It maps to the underlying - OS's file system API providing most of the common operations expected from a file API somewhat in - the vain of java.io.File & java.io.FileInputStream e.g. opening, - renaming, deleting etc. -

-

- Notice that the file system API is somewhat platform specific in its behavior. All paths used the API - should be absolute otherwise they are not guaranteed to work. -

- -

- The main reason java.io.File & java.io.FileInputStream - weren't supported directly has a lot to do with the richness of those two API's. They effectively - allow saving a file anywhere, however mobile devices are far more restrictive and don't allow - apps to see/modify files that are owned by other apps. -

- -

File Paths & App Home

-

- All paths in {@link com.codename1.io.FileSystemStorage} are absolute, this simplifies the issue of portability - significantly since the concept of relativity and current working directory aren't very portable. -

- -

- All URL's use the / as their path separator we try to enforce this behavior even in - Windows. -

- -

- Directories end with the / character and thus can be easily distinguished by their name. -

- -

- The {@link com.codename1.io.FileSystemStorage} API provides a getRoots() call to list the root - directories of the file system (you can then "dig in" via the listFiles API). However, - this is confusing and unintuitive for developers. -

- -

- To simplify the process of creating/reading files we added the getAppHomePath() method. - This method allows us to obtain the path to a directory where files can be stored/read. -

- -

- We can use this directory to place an image to share as we did in the - share sample. -

- -

- Warning: A common Android hack is to write files to the SDCard storage to share - them among apps. Android 4.x disabled the ability to write to arbitrary directories on the SDCard - even when the appropriate permission was requested. -

- -

- A more advanced usage of the {@link com.codename1.io.FileSystemStorage} API can be a - {@link com.codename1.io.FileSystemStorage} Tree: -

- -Simple sample of a tree for the FileSystemStorage API - -

Storage vs. File System

-

- The question of storage vs. file system is often confusing for novice mobile developers. This embeds - two separate questions:

- - -

- The main reasons for the 2 API's are technical. Many OS's provide 2 ways of accessing data - specific to the app and this is reflected within the API. E.g. on Android the - {@link com.codename1.io.FileSystemStorage} maps to API's such as java.io.FileInputStream - whereas the {@link com.codename1.io.Storage} maps to Context.openFileInput(). -

- -

- The secondary reason for the two API's is conceptual. {@link com.codename1.io.FileSystemStorage} is - more powerful and in a sense provides more ways to fail, this is compounded by the complex - on-device behavior of the API. {@link com.codename1.io.Storage} is designed to be friendlier to the - uninitiated and more portable. -

- -

- You should pick {@link com.codename1.io.Storage} unless you have a specific requirement that prevents it. - Some API's such as Capture expect a {@link com.codename1.io.FileSystemStorage} URI - so in those cases this would also be a requirement. -

- -

- Another case where {@link com.codename1.io.FileSystemStorage} is beneficial is the case of hierarchy or - native API usage. If you need a a directory structure or need to communicate with a native - API the {@link com.codename1.io.FileSystemStorage} approach is usually easier.
- Warning: In some OS's the {@link com.codename1.io.FileSystemStorage} API can find the - content of the {@link com.codename1.io.Storage} API. As one is implemented on top of the other. This is - undocumented behavior that can change at any moment! -

- -

Network Manager & Connection Request

-

- One of the more common problems in Network programming is spawning a new thread to handle - the network operations. In Codename One this is done seamlessly and becomes unessential - thanks to the {@link com.codename1.io.NetworkManager}. -

-

- {@link com.codename1.io.NetworkManager} effectively alleviates the need for managing network threads by - managing the complexity of network threading. The connection request class can be used to - facilitate web service requests when coupled with the JSON/XML parsing capabilities. -

-

- To open a connection one needs to use a {@link com.codename1.io.ConnectionRequest} - object, which has some similarities to the networking mechanism in JavaScript but is obviously somewhat more - elaborate.

-

You can send a get request to a URL using something like:

- - - -

- Notice that you can also implement the same thing and much more by avoiding the response - listener code and instead overriding the methods of the {@link com.codename1.io.ConnectionRequest} class - which offers multiple points to override e.g. -

- - - -

- Notice that overriding buildRequestBody(OutputStream) will only work for - POST requests and will replace writing the arguments. -

-

- Important: You don't need to close the output/input streams passed to the - request methods. They are implicitly cleaned up. -

- -

- {@link com.codename1.io.NetworkManager} also supports synchronous requests which work in a similar - way to Dialog via the invokeAndBlock call and thus don't block - the EDT illegally. E.g. you can do something like this: -

- - - -

- Notice that in this case the addToQueueAndWait method returned after the - connection completed. Also notice that this was totally legal to do on the EDT! -

- -

Threading

-

- By default the {@link com.codename1.io.NetworkManager} launches with a single network thread. This is - sufficient for very simple applications that don't do too much networking but if you need to - fetch many images concurrently and perform web services in parallel this might be an issue. -

- -

- Warning: Once you increase the thread count there is no guarantee of order for your requests. - Requests - might not execute in the order with which you added them to the queue! -

-

To update the number of threads use:

- - - -

- All the callbacks in the {@code ConnectionRequest} occur on the network thread and - not on the EDT! -

- -

- There is one exception to this rule which is the postResponse() method designed - to update the UI after the networking code completes. -

- -

- Important: Never change the UI from a {@link com.codename1.io.ConnectionRequest} - callback. You can either use a listener on the {@link com.codename1.io.ConnectionRequest}, use - postResponse() (which is the only exception to this rule) or wrap your UI code with - {@link com.codename1.ui.Display#callSerially(java.lang.Runnable)}. -

- -

Arguments, Headers & Methods

-

- HTTP/S is a complex protocol that expects complex encoded data for its requests. Codename - One tries to simplify and abstract most of these complexities behind common sense API's while - still providing the full low level access you would expect from such an API. -

- -
Arguments
-

- HTTP supports several "request methods", most commonly GET & - POST but also a few others such as HEAD, PUT, - DELETE etc. -

- -

Arguments in HTTP are passed differently between GET and POST - methods. That is what the setPost method in Codename One determines, whether - arguments added to the request should be placed using the GET semantics or the - POST semantics.

- -

So if we continue our example from above we can do something like this:

- - -

- This will implicitly add a get argument with the content of value. Notice that we - don't really care what value is. It's implicitly HTTP encoded based on the get/post semantics. - In this case it will use the get encoding since we passed false to the constructor. -

- -

A simpler implementation could do something like this:

- - - -

- This would be almost identical but doesn't provide the convenience for switching back and - forth between GET/POST and it isn't as fluent. -

- -

We can skip the encoding in complex cases where server code expects illegal HTTP - characters (this happens) using the addArgumentNoEncoding method. We can - also add multiple arguments with the same key using addArgumentArray. -

- -
Methods
-

- As we explained above, the setPost() method allows us to manipulate the - get/post semantics of a request. This implicitly changes the POST - or GET method submitted to the server. -

- -

- However, if you wish to have finer grained control over the submission process e.g. for making a - HEAD request you can do this with code like: -

- - - -
Headers
-

- When communicating with HTTP servers we often pass data within headers mostly for - authentication/authorization but also to convey various properties. -

- -

- Some headers are builtin as direct API's e.g. content type is directly exposed within the API - since it's a pretty common use case. We can set the content type of a post request using: -

- - - -

- We can also add any arbitrary header type we want, e.g. a very common use case is basic - authorization where the authorization header includes the Base64 encoded user/password - combination as such: -

- - - - -

This can be quite tedious to do if you want all requests from your app to use this header. - For this use case you can just use:

- - - -
Server Headers
-

- Server returned headers are a bit trickier to read. We need to subclass the connection request - and override the readHeaders method e.g.: -

- - - -

- Here we can extract the headers one by one to handle complex headers such as cookies, - authentication etc. -

- -
Error Handling
-

- As you noticed above practically all of the methods in the ConectionRequest - throw IOException. This allows you to avoid the try/catch - semantics and just let the error propagate up the chain so it can be handled uniformly by - the application. -

- -

There are two distinct placed where you can handle a networking error:

- - -

- Notice that the {@link com.codename1.io.NetworkManager} error handler takes precedence thus allowing - you to define a global policy for network error handling by consuming errors. -

-

- E.g. if I would like to block all network errors from showing anything to the user I could do - something like this:

- - - -

- The error listener is invoked first with the {@link com.codename1.io.NetworkEvent} matching the - error. Consuming the event prevents it from propagating further down the chain into the - {@link com.codename1.io.ConnectionRequest} callbacks. -

-

- We can also override the error callbacks of the various types in the request e.g. in the case of a - server error code we can do: -

- - - - -

- Important: The error callback callback is triggered in the network thread!
- As a result it can't access the UI to show a Dialog or anything like that. -

- -

- Another approach is to use the setFailSilently(true) method on the - {@link com.codename1.io.ConnectionRequest}. This will prevent the - {@link com.codename1.io.ConnectionRequest} from displaying any errors to the user. It's a very - powerful strategy if you use the synchronous version of the API's e.g.: -

- - - -

- This code will only work with the synchronous "AndWait" version of the method since the response - code will take a while to return for the non-wait version. -

- -
Error Stream
-

- When we get an error code that isn't 200/300 we ignore the result. This is problematic as the - result might contain information we need. E.g. many webservices provide further XML/JSON - based details describing the reason for the error code. -

-

- Calling setReadResponseForErrors(true) will trigger a mode where even errors - will receive the readResponse callback with the error stream. This also means - that API's like getData and the listener API's will also work correctly in - case of error. -

- - -

GZIP

-

- Gzip is a very common compression format based on the lz algorithm, it's used by web servers - around the world to compress data. -

- -

- Codename One supports {@link com.codename1.io.gzip.GZIPInputStream} and - {@link com.codename1.io.gzip.GZIPOutputStream}, which allow you to compress data - seamlessly into a stream and extract compressed data from a stream. This is very useful and - can be applied to every arbitrary stream. -

- -

- Codename One also features a {@link com.codename1.io.gzip.GZConnectionRequest}, which - will automatically unzip an HTTP response if it is indeed gzipped. Notice that some devices (iOS) - always request gzip'ed data and always decompress it for us, however in the case of iOS it - doesn't remove the gziped header. The GZConnectionRequest is aware of such - behaviors so its better to use that when connecting to the network (if applicable). -

- -

- By default GZConnectionRequest doesn't request gzipped data (only unzips it - when its received) but its pretty easy to do so just add the HTTP header - Accept-Encoding: gzip e.g.: -

- - - -

Do the rest as usual and you should have smaller responses from the servers.

- -

File Upload

-

- {@link com.codename1.io.MultipartRequest} tries to simplify the process of uploading a file from - the local device to a remote server. -

- -

- You can always submit data in the buildRequestBody but this is flaky and has - some limitations in terms of devices/size allowed. HTTP standardized file upload capabilities - thru the multipart request protocol, this is implemented by countless servers and is well - documented. Codename One supports this out of the box. -

-

- Since we assume most developers reading this will be familiar with Java here is the way to - implement the multipart upload in the servlet API. -

- - - -

- {@link com.codename1.io.MultipartRequest} is a {@link com.codename1.io.ConnectionRequest} - most stuff you expect from there should work. Even addArgument etc. -

- - -

Parsing

- -

Codename One has several built in parsers for JSON, XML, CSV & Properties formats. You can - use those parsers to read data from the Internet or data that is shipping with your product. E.g. use the - CSV data to setup default values for your application.

- -

- All our parsers are designed with simplicity and small distribution size; they don't validate and will fail - in odd ways when faced with broken data. The main logic behind this is that validation takes up CPU - time on the device where CPU is a precious resource. -

- -
Parsing CSV
- -

- CSV is probably the easiest to use, the "Comma Separated Values" format is just a list of values - separated by commas (or some other character) with new lines to indicate another row in the table. - These usually map well to an Excel spreadsheet or database table and are supported by default in all - spreadsheets. -

- -

- To parse a CSV just use the - CSVParser class as such: -

- - -CSV parsing results, notice the properly escaped parentheses and comma - - -

- The data contains a two dimensional array of the CSV content. You can change the delimiter character - by using the {@code CSVParser} constructor that accepts a character. -

- -

- IMPORTANT: Notice that we used {@link com.codename1.io.CharArrayReader} for - this sample. Normally you would want to use {@link java.util.InputStreamReader} for real world data. -

- -
JSON
- -

- The JSON ("Java Script Object Notation") format is popular on the web for passing values to/from - webservices since it works so well with JavaScript. Parsing JSON is just as easy but has two - different variations. You can use the - {@link com.codename1.io.JSONParser} class to build a tree of the JSON data as such: -

- - - -

- The response is a {@code Map} containing a nested hierarchy of {@code Collection} ({@code java.util.List}), - Strings and numbers to represent the content of the submitted JSON. To extract the data from a specific - path just iterate the {@code Map} keys and recurs into it. -

- -

- The sample below uses results from an API of ice and fire - that queries structured data about the "Song Of Ice & Fire" book series. Here is a sample result - returned from the API for the query - http://www.anapioficeandfire.com/api/characters?page=5&pageSize=3: -

- - - -

- We will place that into a file named "anapioficeandfire.json" in the src directory to make the next - sample simpler: -

- - - -
    -
  1. The {@code JSONParser} returns a {@code Map} which is great if the root object is a {@code Map} - but in some cases its a list of elements (as is the case above). In this case a special case {@code "root"} - element is created to contain the actual list of elements. -
  2. -
  3. We rely that the entries are all maps, this might not be the case for every API type.
  4. -
  5. Notice that the "titles" and "aliases" entries are both lists of elements. We use {@code java.util.List} - to avoid a clash with {@code com.codename1.ui.List}. -
  6. -
- - -Parsed JSON result, clicking the elements opens the URL from the JSON - -

- Tip: The structure of the returned map is sometimes unintuitive when looking at the raw JSON. The easiest - thing to do is set a breakpoint on the method and use the inspect variables capability of your IDE to - inspect the returned element hierarchy while writing the code to extract that data -

- - -

- An alternative approach is to use the static data parse() method of the {@code JSONParser} class and - implement a callback parser e.g.: {@code JSONParser.parse(reader, callback);} -

- -

- Notice that a static version of the method is used! The callback object is an instance of the - {@code JSONParseCallback} interface, which includes multiple methods. These methods are invoked - by the parser to indicate internal parser states, this is similar to the way traditional XML SAX event - parsers work. -

- -
XML Parsing
- -

- The {@link com.codename1.xml.XMLParser} started its life as an HTML parser built for displaying - mobile HTML. That usage has since been deprecated but the parser can still parse many HTML - pages and is very "loose" in terms of verification. This is both good and bad as the parser will work - with invalid data without complaining. -

- -

- The simplest usage of {@link com.codename1.xml.XMLParser} looks a bit like this: -

- - - -

- The {@link com.codename1.xml.Element} contains children and attributes. It represents a tag within the - XML document and even the root document itself. You can iterate over the XML tree to extract the - data from within the XML file. -

- -

- We have a great sample of working with {@code XMLParser} in the - {@link com.codename1.ui.tree.Tree} class. -

- -
XPath Processing
-

- Codename One ships with support to a subset of XPath processing, you can read more about it in - the {@link com.codename1.processing processing package docs}. -

- -

Externalizable Objects

- -

- Codename One provides the {@link com.codename1.io.Externalizable} interface, which is similar - to the Java SE {@link com.codename1.io.Externalizable} interface. - This interface allows an object to declare itself as {@link com.codename1.io.Externalizable} for - serialization (so an object can be stored in a file/storage or sent over the network). However, due to the - lack of reflection and use of obfuscation these objects must be registered with the - {@link com.codename1.io.Util} class. -

- -

- Codename One doesn't support the Java SE Serialization API due to the size issues and - complexities related to obfuscation. -

- -

- The major objects that are supported by default in the Codename One - {@link com.codename1.io.Externalizable} are: - String, Collection, Map, ArrayList, - HashMap, Vector, Hashtable, - Integer, Double, Float, Byte, - Short, Long, Character, Boolean, - Object[], byte[], int[], float[], - long[], double[]. -

- -

Externalizing an object such as h below should work just fine:

- - - -

- However, notice that some things aren't polymorphic e.g. if we will externalize a - String[] we will get back an Object[] since String - arrays aren't detected by the implementation. -

- - -

- Important: The externalization process caches objects so the app will seem to - work and only fail on restart! -

- -

- Implementing the {@link com.codename1.io.Externalizable} interface is only important when we - want to store a proprietary object. In this case we must register the object with the - com.codename1.io.Util class so the externalization algorithm will be able to - recognize it by name by invoking: -

- - - -

- You should do this early on in the app e.g. in the init(Object) but you shouldn't do - it in a static initializer within the object as that might never be invoked! -

- -

- An {@link com.codename1.io.Externalizable} object must have a - default public constructor and must implement the following 4 methods: -

- - -

- The getVersion() method returns the current version of the object allowing the - stored data to change its structure in the future (the version is then passed when internalizing - the object). The object id is a String uniquely representing the object; - it usually corresponds to the class name (in the example above the Unique Name should be - MyClass). -

- -

- Warning: It's a common mistake to use getClass().getName() - to implement getObjectId() and it would seem to work in the - simulator. This isn't the case though!
- Since devices obfuscate the class names this becomes a problem as data is stored in a random - name that changes with every release. -

- -

- Developers need to write the data of the object in the externalize method using the methods in the - data output stream and read the data of the object in the internalize method e.g.: -

- - - -

- Since strings might be null sometimes we also included convenience methods to implement such - externalization. This effectively writes a boolean before writing the UTF to indicate whether the string - is null: -

- - - -

- Assuming we added a new date field to the object we can do the following. Notice that a - Date is really a long value in Java that can be null. - For completeness the full class is presented below:

- - -

Notice that we only need to check for compatibility during the reading process as the writing - process always writes the latest version of the data.

- - diff --git a/CodenameOne/src/com/codename1/io/rest/package.html b/CodenameOne/src/com/codename1/io/rest/package.html deleted file mode 100644 index 054d10479b..0000000000 --- a/CodenameOne/src/com/codename1/io/rest/package.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - -

Simplified REST API

-

- A builder pattern based API to make REST requests with a terse API. These mask the parsing, networking - and error handling behind one simplified call. -

- - diff --git a/CodenameOne/src/com/codename1/io/services/package.html b/CodenameOne/src/com/codename1/io/services/package.html deleted file mode 100644 index 9fd8300454..0000000000 --- a/CodenameOne/src/com/codename1/io/services/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -

- Default WebService implementations -

- - diff --git a/CodenameOne/src/com/codename1/io/tar/package.html b/CodenameOne/src/com/codename1/io/tar/package.html deleted file mode 100644 index 6be4e1c4ab..0000000000 --- a/CodenameOne/src/com/codename1/io/tar/package.html +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - -

- Tar support allowing us to package multiple separate files into a single package which is useful in supporting - hierarchies in a portable way. - This is based on the work contributed in - Issue 754. -

- - diff --git a/CodenameOne/src/com/codename1/javascript/package.html b/CodenameOne/src/com/codename1/javascript/package.html deleted file mode 100644 index 9715f72381..0000000000 --- a/CodenameOne/src/com/codename1/javascript/package.html +++ /dev/null @@ -1,730 +0,0 @@ - - - - - - - - - -

NOTE: The {@link com.codename1.javascript } package is now deprecated. The preferred method of - Java/Javascript interop is to use {@link BrowserComponent#execute(java.lang.String) }, {@link - BrowserComponent#execute(java.lang.String, com.codename1.util.SuccessCallback) }, - {@link BrowserComponent#executeAndWait(java.lang.String) }, etc.. as these work asynchronously (except in the - XXXAndWait() variants, which use invokeAndBlock() to make the calls synchronously.

- -

The Codename One JS Bridge package includes classes that facilitate the - interaction between Java and Javascript in a Codename One application. - It allows both Java to Javascript communication and the reverse via a - mechanism similar to the one employed by Phone Gap/Apache Cordova.

- -

Requirements

- -

The bridge will only run on platforms that include a native browser component. This includes iOS, - Android, Windows, Desktop & JavaScript at this time.

- - -

Usage

- -

The {@link com.codename1.javascript.JavascriptContext} class lays the foundation by enabling you to call - Javascript code directly from Java. It provides automatic type conversion - between Java and Javascript types as follows:

- -

Java to Javascript

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Java TypeJavascript Type -
StringString
Double/Integer/Float/LongNumber
BooleanBoolean
JSObjectObject
nullnull
OtherNot Allowed
- -

Javascript to Java

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Javascript TypeJava Type
NumberDouble
StringString
BooleanBoolean
ObjectJSObject
FunctionJSObject
ArrayJSObject
nullnull
undefinednull
- -

- Note that this conversion table is more verbose than necessary, since Javascript functions - and arrays are, in fact Objects themselves, so those rows are redundant. All Javascript - objects are converted to {@link com.codename1.javascript.JSObject}s. -

- -

Getting Started

- -

In order to start interacting with a Javascript environment, you need to create - a WebBrowser and load a page. Then inside the WebBrowser's onLoad() handler, you - can create a JavascriptContext on the internal BrowserComponent object:

- - - -

Getting Values

- -

The {@link com.codename1.javascript.JavascriptContext#get(String)} method is used to get values from Javascript. - It takes an arbitrary Javascript expression, executes it, and returns the - result, after converting it to the corresponding Java type. E.g. if the result - is a String, it will return a String and if it is a Number it will return a - java Double object. If the result is an Object, it will return a {@link com.codename1.javascript.JSObject}.

- -

The following is a simple example that retrieves the document content, which - is a string:

- - - -

If you run this example in the simulator, you'll see something like the following:

- -

-

- -
-

- -

Note: You don't see the WebBrowser in the background here due to a bug in the simulator. - If you run this example on a device, you will see the WebBrowser component in the background.

- -

Returning Numeric Values

- -

As mentioned in the conversion table above, numeric values are automatically - converted to java.lang.Double objects. The following example, returns the width and height - properties of the window for use in Java.

- - - -

The result, when run in the simulator would be something like:

- -

-

-

- - -

Returning Objects

- -

The previous examples involved only primitive return values. The {@link com.codename1.javascript.JavascriptContext} - abstraction, - in these cases, doesn't offer a whole lot of added-value over just using the - BrowserComponent.executeJavascriptAndReturnString() - method. The real value is when we are dealing with objects.

-

The following example obtains a reference to the window object and wraps it in a - proxy {@link com.codename1.javascript.JSObject} class so that we can work directly with the window object:

- - - -

This code produces the exact same result as the previous example. The difference - is the intermediary step of wrapping the window object in a {@link com.codename1.javascript.JSObject}, and - obtaining the outerHeight and outerWidth properties directly via that proxy object.

- -

You can obtain a {@link com.codename1.javascript.JSObject} proxy for any Javascript object, even ones that you create - on the fly. The following example creates an anonymous object with some keys and values - and uses a {@link com.codename1.javascript.JSObject} proxy to interact with this object from Java.

- - - -

The result is as follows:

- -

-

-

- -

See Working With Objects for more information - about working with the {@link com.codename1.javascript.JSObject} class.

- -

Returning Functions and Arrays

- -

In Javascript, functions and arrays are just objects, so these are also encapsulated as {@link - com.codename1.javascript.JSObject} - proxies. See Working with Arrays and - Workin with Functions for more details on how to work - with these values via the {@link com.codename1.javascript.JSObject} interface.

- -

Setting Values

- -

Just as you can get values from Javascript using {@link com.codename1.javascript.JavascriptContext}'s get() method, - you can - also set values via {@link com.codename1.javascript.JavascriptContext#set(String,Object)}.

- -

The following is a simple example that sets the location, and causes it to redirect to - a different page:

- - - - -

If you run this example, you should see your browser display the Codename One website after - a redirect.

-

-

-

- - -

Setting Object Values

- -

The previous example showed us setting a primitive String value. You can do the same with other - primitives like numbers and booleans, but you can also set Object values using the set() method. -

- -

The following example creates an anonymous Javascript object, wraps it in a {@link com.codename1.javascript.JSObject} - proxy, - sets some values on it, then sets the object as a property of the top-level window object.

- - - -

As a result, you should see the following content set as the body of the HTML page in the - WebBrowser. Note that we can refer to the "steve" object that we just set directly/globally - because the "window" object's properties are always available directly through the global - namespace in Javascript.

-

-

-

- -

Working with Objects

- -

Previously examples showed how to obtain a {@link com.codename1.javascript.JSObject} proxy to a Javascript object. - There are 4 ways to get a {@link com.codename1.javascript.JSObject}:

-
    -
  1. Create an anonymous object:
    JSObject obj = (JSObject)ctx.get("{}");
  2. -
  3. Reference an existing object directly:
    JSObject obj = (JSObject)ctx.get("window.location"); -
  4. -
  5. As the result of a Javascript expression or function call: -
    JSObject obj = (JSObject)ctx.get("document.getElementById('mydiv')") -
  6. -
  7. Retrieve an Object member variable from another JSObject: -
    JSObject obj = (JSObject)otherObj.get("aPropertyThatIsAnObject") -
  8. -
- -

{@link com.codename1.javascript.JSObject}s are essentially just proxies around a Javascript object. Any calls to - retrieve - properties from a {@link com.codename1.javascript.JSObject} are just sent directly to the Javascript context, and - the result - returned. The {@link com.codename1.javascript.JSObject} object doesn't store copies the javascript object's - properties. It just - retrieves them as they are required via the {@link com.codename1.javascript.JSObject#get(String)} method.

- -

Getting Simple Values

- -

You can always retrieve the properties of an object using the {@link com.codename1.javascript.JSObject#get(String)} - method. It takes the name of the property - as a parameter, and returns its value, converted to the appropriate Java type. (e.g. if it is a String, - it returns a String, if it is a number it returns a Double, and if it is an Object, it returns an object.

- -

E.g.

- -

-String name = (String)obj.get("name");
-Double age = (Double)obj.get("age");
-
- -
- Is equivalent to the following javascript: -
- - var name = obj.name; - var age = obj.age; - -
- Assuming that the obj variable in Java is a proxy for the same obj variable - in the javascript example. -

- -

Getting Nested Object Values

- -

Often, in Javascript, an object contains a heirarchy of nested child objects. E.g.

- -

-var obj = {
-    name : 'Steve',
-    position : {
-        x : 100,
-        y : 105,
-        z : -25
-    }
-}
-
-

- -

In this case you may want to obtain the x coordinate of the nested position object. {@link JSObject} - allows - you to use the dot '.' notation for referencing sub-properties like this. E.g.
- -

Double x = (Double)obj.get("position.x")
- -

-

This feature raises the issue of how, then, to access properties that contain a '.' in its name. E.g.

-

-var obj = {
-    name : 'Steve',
-    position : {
-        x : 100,
-        y : 105,
-        z : -25
-    },
-    'position.x' : 200
-}
-
-

- -

In this example there is a top-level property named 'position.x' as well as a property at the component address position.x. - This is a contrived example that is meant to be somewhat confusing in order to demonstrate how to differentiate - between requests for properties in the child object heirarchy and top-level properties that happen to - include a '.' in the property name.

- -

We can force the retrieval of a top-level property by wrapping the key in single quotes:

-

-

Double x1 = (Double)obj.get("'position.x'")
-

- -

This would return - 200 - for the above example, whereas: -

-

-

Double x2 = (Double)obj.get("position.x")
-

-

Would return - 100 -

-. - -

Setting Object Values

- -

The {@link com.codename1.javascript.JSObject#set(String,Object)} method works the same as the {@link - com.codename1.javascript.JavascriptContext#set(String,Object)} method except that it treats the local - object as the root node. It allows you to easily set properties on the object. Values set here should - be provided using Java values as they will automatically be converted to the appropriate associated Javascript - type. If you are setting an Object as a value, then you'll need to set it as a {@link - com.codename1.javascript.JSObject} and not a string - representation of the object. This is because Strings will just be converted to Javascript strings.

- -

Properties set via the {@link com.codename1.javascript.JSObject#set(String,Object)} method modify the underlying - Javascript object directly so that the change - is immediately effective inside the javascript environment. -

-

Just as with the {@link com.codename1.javascript.JSObject#get(String)} method, you can set the values of direct - properties or nested properties using - the dot '.' notation. And just like {@link com.codename1.javascript.JSObject#get(String)}, you can force setting a - direct property in cases where the property - name includes a '.', by wrapping the key inside single quotes. - -

-

E.g.:

-

-// Create a team object , and leave city null for now.
-JSObject blueJays = (JSObject)ctx.get("{name : 'Blue Jays', city : null}");
-
-// Create a city object and leave country null for now.
-JSObject toronto = (JSObject)ctx.get("{name : 'Toronto', country : null}");
-
-// Create a country object
-JSObject canada = (JSObject)ctx.get("{name : 'Canada'}");
-
-// Set the team's city to toronto
-blueJays.set("city", toronto);
-
-// Set toronto's country to canada
-toronto.set("country", canada);
-
-// Retrieve the name of the country where the blue jays play
-String countryName = (String)blueJays.get("city.country.name");
-       // Should contain "Canada"
-
-// Change the name of Canada to "Canuck land" using nested 
-// dot notation on the blueJays object.
-
-blueJays.set("city.country.name", "Canuck land");
-
-String blueJaysCountry = (String)blueJays.get("city.country.name");
-String torontoCountry = (String)tornoto.get("country.name");
-String canadaName = (String)canada.get("name");
-
-//Note that all of these should be equal and contain "Canuck land"
-
- - -

Calling Object Methods

- -

The {@link com.codename1.javascript.JSObject#call(String,Object)} method allows you to call javascript methods that - are members of the underlying object. It arguments are passed as an - Object[] array. These will be automatically converted from the Java type to the corresponding - Javascript type. Java type conversion are the same as using the {@link - com.codename1.javascript.JavascriptContext#set(String,Object)} method. -

- -

The following example shows an object with a simple add() method - that just adds two numbers together:

-

-JSObject obj = (JSObject)ctx.get("{ add : function(a,b){ return a+b;}}");
-Double result = (Double)obj.call("add", 
-    new Object[]{new Integer(1), new Integer(3)}
-);
-
-// Result should be 4.0
-
-

- -

Working with Arrays

- -

In javascript, arrays are just objects that include a special ability to be iterated. You can use the alternate - version of {@link com.codename1.javascript.JSObject#get(int)} which takes an int as a parameter to - retrieve the elements of an array.

- -

For example, consider the following javascript object:

-

-var obj = {
-    name : 'Blue Jays',
-    players : [
-        { name : 'George Bell', age : 31},
-        { name : 'Tony Fernandez', age : 34},
-        { name : 'Lloyd Moseby', age : 29}
-    ]
-}
-
-        
-

- -

Then assuming we have a {@link com.codename1.javascript.JSObject} proxy for this object, we could loop through the - players - array and output the name and age of each player as follows:

- -

-JObject players = (JObject)obj.get("players");
-int len = ((Double)players.get("length")).intValue();
-for ( int i=0; i<len; i++){
-    JSObject player = (JSObject)players.get(i);
-    Log.p("Name : "+player.get("name")+" age : "+player.get("age"));
-}
-                
- - - -

Calling Java Methods from Javascript

- -

So far, our examples have been limited to Java calling into Javascript. However, it may be - useful to be able to also go the other way: call java methods from Javascript. Some applications - of this might include:

- - -

The Codename One JS bridge supports javascript to java method calling by way of the {@link - com.codename1.javascript.JSFunction} interface - and the {@link com.codename1.javascript.JSObject#set(String,Object)} methods on the {@link - com.codename1.javascript.JSObject} class. You can implement a {@link com.codename1.javascript.JSFunction} - object and register it as a callback with a {@link com.codename1.javascript.JSObject}, then you will be able to - execute this object's apply method via a Javascript proxy.

- -

As an example, let's implement a simple logging function:

- -

-JSObject logger = (JSObject)ctx.get("{}");
-logger.set("log", new JSFunction(){
-
-    public void apply(JSObject self, Object[] args) {
-        String msg = (String)args[0];
-        Log.p("[Javascript Logger] "+msg);
-    }
-    
-});
-
-ctx.set("window.logger", logger);
-
-
-c.executeAndReturnString("logger.log('This is a test message');");
-
-

- -

If you execute this code in the simulator, you'll see the following output in the console:

- -
[EDT] 0:0:0,0 - [Javascript Logger] This is a test message
- -

Running it on a device will yield similar output in the device log file.

- -

Let's step through this code to see what is happening. First we create a new, empty javascript object - and wrap it in a JSObject proxy. Then we use the {@link com.codename1.javascript.JSObject}'s {@link - com.codename1.javascript.JSObject#set(String,Object)} method to add an anonymous {@link - com.codename1.javascript.JSFunction} - object to it with the propery of "log". This step registers a method proxy on the Javascript side that acts just - like a normal javascript method, but which actually triggers the {@link com.codename1.javascript.JSFunction}'s - {@link com.codename1.javascript.JSFunction#apply(JSObject,Object[])} method.

- -

We then set this logger object to the global javascript scope by making it a direct child - of the window object. Finally we issue a Javascript method call to logger.log(). This - is what effectively calls the apply() method on our {@link com.codename1.javascript.JSFunction} object.

- -

Caveats

- -

JSFunction callbacks are executed asynchronously so as to prevent deadlocks. This means that you - cannot - return a value from this method using a return statement (hence the reason why the interface definition for {@link - com.codename1.javascript.JSFunction#apply(JSObject,Object[])} is void. -

-

If you want to return a value back to Javascript, then you'll need to do it by providing a - callback function as one of the parameters, and call this callback method from inside the {@link - com.codename1.javascript.JSFunction#apply(JSObject,Object[])} - method upon completion.

- -

Example: Passing a Javascript Callback to Your Callback

- -

Since {@link com.codename1.javascript.JSFunction} callbacks are executed asynchronously, if you want to be able to - return a result back to Javascript, you will - need to do this via a Javascript callback. This is quite a common pattern in Javascript since it is single threaded - and relies - upon non-blocking patterns.

- -

As an example, let's create a {@link com.codename1.javascript.JSFunction} callback that adds two numbers together and - returns the result to Javascript via a callback:

- -

First we will create the {@link com.codename1.javascript.JSFunction} object to perform the addition, as follows:

-

-WebBrowser b = new WebBrowser(){
-    protected void onLoad(String url){
-        JSObject window = (JSObject)ctx.get("window");
-        window.set("addAsync", new JSFunction(){
-
-            public void apply(JSObject self, final Object[] args) {
-                Double a = (Double)args[0];
-                Double b = (Double)args[1];
-                JSObject callback = (JSObject)args[2];
-
-                double result = a.doubleValue() + b.doubleValue();
-                callback.call(new Object[]{new Double(result)});
-
-            }
-
-        });
-    }
-};
-
-b.setURL("jar:///ca/weblite/codename1/tests/AddAsync.html");
-                
-

-

In this snippet, we start by obtaining a reference to the "window" object. We then add a method to this object named - "addAsync". This method is a {@link com.codename1.javascript.JSFunction} - object that we implement inline. The apply() method of the {@link com.codename1.javascript.JSFunction} object is the - Java method that will be executed when the addAsync method is called - from Javascript. In this case the addAsync method expects three parameters:

-
    -
  1. The two numbers that are being added together.
  2. -
  3. A Javascript callback method that will be executed when completed and passed the result of the addition - as a parameter. -
  4. -
-

Notice that all numerical arguments are converted to Java Double objects, and the callback function is converted to a - {@link com.codename1.javascript.JSObject} object. Also notice the use - of callback.call(), which just calls the callback as a function itself. With this variant of - the call() method, - the window object is used as this. Notice also that we pass the result inside an - Object[] array. This array will be expanded to - the direct javascript function parameters. (i.e. it will not pass an array as the parameter to the javascript - method, the array elements are extracted - and passed individually.

- - -

Now, let's look at the HTML page contents for our example:

-

-<!DOCTYPE html>
-<html>
-    <head>
-        <title>Addition Example</title>
-    </head>
-    <body>
-        <div>Addition Example</div>
-        <p><input type="text" size="4" id="input1"/> +
-            <input type="text" size="4" id="input2"/> =
-            <span id="result"></span>
-        </p>
-        <p><button id="calculate">Calculate</button></p>
-        <script src="AddAsync.js"></script>
-    </body>
-</html>
-                        
-

-

Our HTML simply includes two text fields (to input the values to be added together), a button to initiate the - calculation, - and a <span> tag where the result will be placed when the calculation is complete.

-

Finally it includes the AddAsync.js Javascript file (which is placed in the same directory as the AddAsync.html file. - Its - contents are as follows:

-

-
-document
-    .getElementById('calculate')
-    .addEventListener('click', function(){
-        var aField = document.getElementById('input1');
-        var bField = document.getElementById('input2');
-        var a = parseFloat(aField.value);
-        var b = parseFloat(bField.value);
-        window.addAsync(a, b, function(result){
-           document.getElementById('result').innerHTML = result;
-        });
-    }, true);
-
-                        
-

- -

This script attaches an event handler to the calculate - button that gets the values from the two input fields and - passes it to the window.addAsync() method for calculation. The addAsync() - method is actually our java JSFunction that we implemented earlier. -

- -

- One small word about the placement of these files: This example is taken from a class ca.weblite.codename1.tests.CodenameOneTests. - The AddAsync.html and AddAsync.js files are included in the same directory as the CodenameOneTests.java file ( - i.e. /ca/weblite/codename1/tests). We used the WebBrowser's setURL() method to load the AddAsync.html - file from an - absolute path using jar: protocol. Currently this is the best way of loading local HTML files into - a WebBrowser object (i.e. use the jar: protocol and provide an absolute path). -

- -

The result of running this app is as follows:

-

-

-

- -

Example: Exposing the Camera to Javascript

- -

The following creates a Javascript function for taking photos on a mobile device. It involves a simple webpage with a - "Capture" button. When the user - clicks this button, it will dispatch a function call to CodenameOne to access the device's camera. After the user - takes a picture, CodenameOne will - execute a Javascript callback to add the picture to the webpage.

- -

The HTML page source is as follows:

- - -

This loads the CameraExample.js script:

-
-document.getElementById('capture')
-    .addEventListener('click', function(){
-        camera.capture(function(url){
-            if ( url == null ){
-                // No image was provided
-                return;
-            }
-            var results = document.getElementById('results');
-            results.appendChild(document.createTextNode("testing"));
-            var img = document.createElement('img');
-            img.setAttribute('src',url);
-            img.setAttribute('width', '100');
-            img.setAttribute('height', '100');
-            results.appendChild(img);
-        })
-    }, true);
-
-
- -

The CameraExample.js script attaches a listener to the 'click' event of the "Capture" button which simply calls the - camera.capture() method, - which is actually a JSFunction that has been registered with the Javascript runtime. This actually calls into Java. -

-

We pass a callback function into camera.capture() which will be executed upon successfully completion of - the camera. This is a common - programming pattern in Javascript. If a non-null URL is passed to this callback function, it is expected to be the - URL of the image (it will be - a local file URL.

- -

The Java code that powers this example is as follows:

- - -

This example puts together most of the features of the CodenameOne-JS library.

-
    -
  1. It creates a new JSObject from within Java code to serve as the camera object.
  2. -
  3. It registers a JSFunction callback as a Javascript function which is added as a method to the camera object. -
  4. -
  5. It shows the use of the call() method of JSObject to call the callback function that - was - provided by Javascript from inside - the JSFunction's apply() method. -
  6. -
- - - diff --git a/CodenameOne/src/com/codename1/l10n/package.html b/CodenameOne/src/com/codename1/l10n/package.html deleted file mode 100644 index d7d4e6e475..0000000000 --- a/CodenameOne/src/com/codename1/l10n/package.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - -

- The Localization API allows developers to adapt their applications to different geographic locales and - conventions. -

-

Portable Localization

-

- Most of the classes within this package are clones of Java SE classes such as {@link - com.codename1.l10n.SimpleDateFormat} - vs. {@link java.text.SimpleDateFormat}. The main motivation of placing these classes here and using the - cloned version is portability. -

-

- If we would use {@link java.text.SimpleDateFormat} its behavior would be slightly different on Android - or in the simulator vs. its behavior on iOS. That is because the implementation would be radically different. - When you use {@link com.codename1.l10n.SimpleDateFormat} the implementation might be missing - some pieces but it would be more consistent with the implementation you would get on the device which - is always preferable. -

-

L10NManager

-

- The localization manager allows adapting values for display in different locales thru parsing and formatting - capabilities (similar to JavaSE's DateFormat/NumberFormat). It also includes language/locale/currency - related API's similar to Locale/currency API's from JavaSE.
- The sample code below just lists the various capabilities of the API: -

- -Localization formatting/parsing and information - - - diff --git a/CodenameOne/src/com/codename1/location/package.html b/CodenameOne/src/com/codename1/location/package.html deleted file mode 100644 index 00034bcfb3..0000000000 --- a/CodenameOne/src/com/codename1/location/package.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - -

- Abstraction of location services (GPS/Geofencing etc.) providing user global positioning and monitoring over - such changes both in the foreground and background. -

- -

- Trivial one time usage of location data can look like this sample: -

- - -

- You can also track location in the foreground using API calls like this: -

- - -

- Geofencing allows tracking whether a user entered a specific region, this can work when the app is completely - in the background and is very efficient in terms of battery life: -

- - - diff --git a/CodenameOne/src/com/codename1/maps/layers/package.html b/CodenameOne/src/com/codename1/maps/layers/package.html deleted file mode 100644 index f510b0f1bb..0000000000 --- a/CodenameOne/src/com/codename1/maps/layers/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -

- The Layers are elements that are displayed on the map. -

- - diff --git a/CodenameOne/src/com/codename1/maps/package.html b/CodenameOne/src/com/codename1/maps/package.html deleted file mode 100644 index d400fb9325..0000000000 --- a/CodenameOne/src/com/codename1/maps/package.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - -

- The mapping API allows developers to use maps in their applications, add layers - on top of the map and to enhance the API with additional Layers, Providers and functionality. - - The mapping was contributed by Roman Kamyk - -

- - diff --git a/CodenameOne/src/com/codename1/maps/providers/package.html b/CodenameOne/src/com/codename1/maps/providers/package.html deleted file mode 100644 index 476aa90fdb..0000000000 --- a/CodenameOne/src/com/codename1/maps/providers/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -

- These are the map providers, currently http://www.openstreetmap.org/ is supported. -

- - diff --git a/CodenameOne/src/com/codename1/media/Media.java b/CodenameOne/src/com/codename1/media/Media.java index c84be8a334..23ae996bb3 100644 --- a/CodenameOne/src/com/codename1/media/Media.java +++ b/CodenameOne/src/com/codename1/media/Media.java @@ -354,13 +354,12 @@ public interface Media { /// video should include embedded native controls. String VARIABLE_NATIVE_CONTRLOLS_EMBEDDED = "nativeControlsVisible"; - /** - * Optional boolean flag to enable an Android-specific workaround for flaky - * black-frame previews after {@link #setTime(int)} on paused video. - *

The default is {@code false}. When enabled, Android may perform an - * additional internal refresh seek to force a frame redraw without changing - * behaviour on other platforms. - */ + /// Optional boolean flag to enable an Android-specific workaround for flaky + /// black-frame previews after `setTime(int)` on paused video. + /// + /// The default is `false`. When enabled, Android may perform an additional + /// internal refresh seek to force a frame redraw without changing behaviour + /// on other platforms. String VARIABLE_ANDROID_SEEK_PREVIEW_WORKAROUND = "androidSeekPreviewWorkaround"; /// Starts playing or recording the media file diff --git a/CodenameOne/src/com/codename1/media/package.html b/CodenameOne/src/com/codename1/media/package.html deleted file mode 100644 index 7fb03670c2..0000000000 --- a/CodenameOne/src/com/codename1/media/package.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - -

- Video and Audio playback support are handled within this package using the - {@link com.codename1.media.Media} & {@link com.codename1.media.MediaManager} APIs. - Said API's allow for video playback both within a native full screen player and embedded within - an application screen. -

-

- Simplified video playback API is also available via the {@link com.codename1.components.MediaPlayer} class. - Capture/recording is handled separately for the most part thru the - {@link com.codename1.capture.Capture} API. However, there is some basic low level recording - functionality within {@link com.codename1.media.MediaManager} as well. -

- -

- The code below demonstrates capturing and playing back audio files using this API: -

- -Captured recordings in the demo - -

- The sample code below demonstrates simple video playback. -

- -Media player sample - - diff --git a/CodenameOne/src/com/codename1/messaging/package.html b/CodenameOne/src/com/codename1/messaging/package.html deleted file mode 100644 index 81f86fe01d..0000000000 --- a/CodenameOne/src/com/codename1/messaging/package.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - -

- Send e-mail messages through underlying platforms e-mail clients or thru the Codename One cloud. -

-

- You can send messages and include attachments by using the platform native email client like this: -

- -

- The following code demonstrates sending an email via the Codename One cloud, notice that this is a pro - specific feature: -

- - - - diff --git a/CodenameOne/src/com/codename1/notifications/package.html b/CodenameOne/src/com/codename1/notifications/package.html deleted file mode 100644 index 65a3e01eba..0000000000 --- a/CodenameOne/src/com/codename1/notifications/package.html +++ /dev/null @@ -1,111 +0,0 @@ - - - - Local Notifications - - -

Local Notification API

-

Local notifications are similar to push notifications, except that they are initiated locally by the app, rather than - remotely. - They are useful for communicating information to the user while the app is running in the background, since they - manifest - themselves as pop-up notifications on supported devices. -

- -

Sending Notifications

- -

The process for sending a notification is:

- - - -

Notifications can either be set up as one-time only or as repeating.

- -

Example Sending Notification

-
-        {@code
-        LocalNotification n = new LocalNotification();
-        n.setId("demo-notification");
-        n.setAlertBody("It's time to take a break and look at me");
-        n.setAlertTitle("Break Time!");
-        n.setAlertSound("/notification_sound_bells.mp3"); //file name must begin with notification_sound
-
-
-        Display.getInstance().scheduleLocalNotification(
-                n,
-                System.currentTimeMillis() + 10 * 1000, // fire date/time
-                LocalNotification.REPEAT_MINUTE  // Whether to repeat and what frequency
-        );
-      }
-    
-

The resulting notification will look like

- -

- -

The above screenshot was taken on the iOS simulator.

- -

Receiving Notifications

- -

The API for receiving/handling local notifications is also similar to push. Your application's main lifecycle class - needs - to implement the {@link com.codename1.notifications.LocalNotificationCallback} interface which includes a single - method: {@link com.codename1.notifications.LocalNotificationCallback#notificationReceived(String)}

- - -

The {@literal notificationId } parameter will match the {@literal id} value of the notification as set using - {@link com.codename1.notifications.LocalNotification#setId(String)}.

- -

Example Receiving Notification

-
-        {@code
-        public class BackgroundLocationDemo implements LocalNotificationCallback {
-            //...
-
-            public void init(Object context) {
-                //...
-            }
-
-            public void start() {
-                //...
-
-            }
-
-            public void stop() {
-                //...
-            }
-
-            public void destroy() {
-                //...
-            }
-
-            public void localNotificationReceived(String notificationId) {
-                System.out.println("Received local notification "+notificationId);
-            }
-        }
-       }
-     
- -

NOTE: {@link - com.codename1.notifications.LocalNotificationCallback#localNotificationReceived(String)} - is only called when the user responds to the notification by tapping on the alert. If the user doesn't opt to - click on the notification, then this event handler will never be fired.

- -

Cancelling Notifications

- -

Repeating notifications will continue until they are canceled by the app. You can cancel a single notification by - calling {@link com.codename1.ui.Display#cancelLocalNotification(String)}

- -

Where {@literal notificationId} is the string id that was set for the notification using {@link - com.codename1.notifications.LocalNotification#setId(String)}. - -

Sample App

- -

You can see a full sample that uses the new local notifications API - here. -

- - diff --git a/CodenameOne/src/com/codename1/payment/package.html b/CodenameOne/src/com/codename1/payment/package.html deleted file mode 100644 index 3c934b0379..0000000000 --- a/CodenameOne/src/com/codename1/payment/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -

- In-App Billing/Purchase API's are abstracted by this package. It encapsulates the different types - of vendor stores and payment API's available on the market. -

- - diff --git a/CodenameOne/src/com/codename1/processing/package.html b/CodenameOne/src/com/codename1/processing/package.html deleted file mode 100644 index dd0cd0f63e..0000000000 --- a/CodenameOne/src/com/codename1/processing/package.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - -

XPath based expression language designed to assist in JSON/XML parsing/generating

-

- The {@link com.codename1.processing.Result} class provides a subset of - XPath, but it is not limited to just XML - documents, it can also work with JSON documents, and even with raw {@link java.util.Map} objects. -

- -

- As an example, we'll demonstrate how to process a response from the - Google Reverse Geocoder API. - Lets start with this XML snippet: -

- - - -

- We want to extract some of the data above into simpler string results. We can do this using: -

- - - -

- If you are at all familiar with processing responses from webservices, you will notice that what would - normally require several lines of code of selecting and testing nodes in regular java can now be - done in a single line using the new path expressions. -

- -

- In the code above, input can be any of: -

- - -

- To use the expression processor when calling a webservice, you could use something like the following to - parse JSON (notice this is interchangeable between JSON and XML): -

- - - -

- The returned JSON looks something like this (notice it's snipped because the data is too long): -

- - - -Running the geocode sample above in the simulator - - -

The XML processor currently handles global selections by using a double slash anywhere within the - expression, for example:

- - - -
NOTE: Notice that Google's JSON webservice uses plural form for each of - the node names in that API (ie. results, address_components, and types) where they don't in the XML services - (ie result, address_component etc.). -
- -

Example 2

-

It also possible to do some more complex expressions. We'll use the following XML fragment for the next batch of - examples:

- - - -

Above, if you want to select the IDs of all players that are ranked in the top 2, you can use an - expression like:

- - -

(Notice above that the expression is using an attribute for selecting both rank and id. In JSON - documents, if you attempt to select an attribute, it will look for a child node under the attribute name you ask - for).

- -

If a document is ordered, you might want to select nodes by their position, for example:

- - -

It is also possible to select parent nodes, by using the �..' expression. For example:

- - -

Above, we globally find a lastname element with a value of �Hewitt', then grab the parent node of - lastname which happens to be the player node, then grab the id attribute from the player node. - Alternatively, you could get the same result from the following simpler statement:

- - - -

It is also possible to nest expressions, for example:

- - - -

In the above example, if the player node had an address object, we'd be selecting all players from Canada. - This is a simple example of a nested expression, but they can get much more complex, which will be - required as the documents themselves get more complex.
Moving on, to select a node based - on the existence of an attribute:

- - - -

Above, we selected the IDs of all ranked players. Conversely, we can select the non-ranked players like this:

- - - -

(Logical not (!) operators currently are not implemented).
You can also select by the existence - of a child node.

- - -

Above, we selected all players that have a middle name.
- Keep in mind that the Codename One path expression language is not a full implementation of - XPath 1.0, but does already handle many of the most useful features of the specification.

- - diff --git a/CodenameOne/src/com/codename1/properties/package.html b/CodenameOne/src/com/codename1/properties/package.html deleted file mode 100644 index e7d581a820..0000000000 --- a/CodenameOne/src/com/codename1/properties/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -

- High level property objects that allow us to replace getters/setters in business objects with more convenient - storage/parsing mappings while retaining type safety. -

- - diff --git a/CodenameOne/src/com/codename1/push/package.html b/CodenameOne/src/com/codename1/push/package.html deleted file mode 100644 index c5858fd4f1..0000000000 --- a/CodenameOne/src/com/codename1/push/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -

- Push notification support using either device specific protocols when available -

- - diff --git a/CodenameOne/src/com/codename1/share/package.html b/CodenameOne/src/com/codename1/share/package.html deleted file mode 100644 index 38be65b7ca..0000000000 --- a/CodenameOne/src/com/codename1/share/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -

- Sharing services, that can be registered on the ShareButton -

- - diff --git a/CodenameOne/src/com/codename1/social/package.html b/CodenameOne/src/com/codename1/social/package.html deleted file mode 100644 index 1e423354b1..0000000000 --- a/CodenameOne/src/com/codename1/social/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -

- Connectors for native social network SDK's -

- - diff --git a/CodenameOne/src/com/codename1/system/package.html b/CodenameOne/src/com/codename1/system/package.html deleted file mode 100644 index 400f9a20ef..0000000000 --- a/CodenameOne/src/com/codename1/system/package.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - -

- Low level calls into the Codename One system, including - - support for making platform native API calls. Notice - that when we say "native" we do not mean C/C++ always but rather the platforms "native" environment. So in the - case of Android the Java code will be invoked with full access to the Android API's, in case of iOS an Objective-C - or Swift message would be sent and so forth. -

-

- Native interfaces are designed to only allow primitive types, Strings, arrays (single dimension only!) of primitives - and PeerComponent values. Any other type of parameter/return type is prohibited. However, once in the native layer - the native code can act freely and query the Java layer for additional information.
- Furthermore, native methods should avoid features such as overloading, varargs (or any Java 5+ feature for that - matter) - to allow portability for languages that do not support such features (e.g. C).
- Important! Do not rely on pass by reference/value behavior since they vary between platforms. -

-

- Implementing a native layer effectively means: -

-
    -
  1. Creating an interface that extends NativeInterface and only defines methods with the arguments/return - values declared in the previous paragraph. -
  2. -
  3. Creating the proper native implementation hierarchy based on the call conventions for every platform - within the native directory -
  4. -
-

- E.g. to create a simple hello world interface do something like: -

-
-            package com.my.code;
-            public interface MyNative extends NativeInteface {
-                  String helloWorld(String hi);
-            }
-        
-

- Then to use that interface use MyNative my = (MyNative)NativeLookup.create(MyNative.class);
- Notice that for this to work you must implement the native code on all supported platforms! -

-

- To implement the native code use the following convention. For Java based platforms (Android, RIM, J2ME): -

-

- Just create a Java class that resides in the same package as the NativeInterface you created - and bares the same name with Impl appended e.g.: MyNativeImpl. So for these platforms the code - would look something like this: -

-
-            package com.my.code;
-            public class MyNativeImpl implements MyNative {
-                  public String helloWorld(String hi) {
-                       // code that can invoke Android/RIM/J2ME respectively
-                  }
-            }
-        
-

- Notice that this code will only be compiled on the server build and is not compiled on the client. - These sources should be placed under the appropriate folder in the native directory and are sent to the - server for compilation. -

-

- For iOS, one would need to define a class matching the name of the package and the class name - combined where the "." elements are replaced by underscores. This class can be implemented in Objective-C - (by providing both a header and an "m" file) or in Swift. Objective-C classes follow this convention e.g.: -

-
-@interface com_my_code_MyNative : NSObject {
-}
-- (id)init;
-- (NSString*)helloWorld:(NSString *)param1;
-@end
-        
-

- Notice that the parameters in Objective-C are named which has no equivalent in Java. That is why the native - method in Objective-C MUST follow the convention of naming the parameters "param1", "param2" etc. for all - the native method implementations. Java arrays are converted to NSData objects to allow features such as length - indication. -

- -

- PeerComponent return values are automatically translated to the platform native peer as an expected return - value. E.g. for a native method such as this: PeerComponent createPeer();
- Android native implementation would need: View createPeer();
- While RIM would expect: Field createPeer()
- The iphone would need to return a pointer to a view e.g.: - (UIView*)createPeer; - J2ME doesn't support native peers hence any method that returns a native peer would always return null.
-

- - diff --git a/CodenameOne/src/com/codename1/testing/package.html b/CodenameOne/src/com/codename1/testing/package.html deleted file mode 100644 index 0fe3b84499..0000000000 --- a/CodenameOne/src/com/codename1/testing/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - -

- This package contains everything necessary for unit tests, automation of tests and everything in between. -

- - diff --git a/CodenameOne/src/com/codename1/ui/animations/package.html b/CodenameOne/src/com/codename1/ui/animations/package.html deleted file mode 100644 index afd7892db6..0000000000 --- a/CodenameOne/src/com/codename1/ui/animations/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - -All components are animatable by potential and additional animations (unrelated -to a specific component) can be installed on the fly, transitions between -forms are also handled as part of this package. Animation thread handling -and painting is handled uniformly to avoid the complexity of threading and -its potential performance penalty on small devices. - - diff --git a/CodenameOne/src/com/codename1/ui/events/package.html b/CodenameOne/src/com/codename1/ui/events/package.html deleted file mode 100644 index 11f6b80d71..0000000000 --- a/CodenameOne/src/com/codename1/ui/events/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - -

- Observable pattern event listeners in the spirit of AWT 1.1's event - dispatching architecture, all events are dispatched on the EDT (Event Dispatch Thread). - See the overview documentation for further information and {@link com.codename1.ui.Display}. -

- - diff --git a/CodenameOne/src/com/codename1/ui/geom/package.html b/CodenameOne/src/com/codename1/ui/geom/package.html deleted file mode 100644 index a4be38bccf..0000000000 --- a/CodenameOne/src/com/codename1/ui/geom/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -

- Contains classes related to geometry locations and calculations such as - rectangle and size -

- - diff --git a/CodenameOne/src/com/codename1/ui/html/package.html b/CodenameOne/src/com/codename1/ui/html/package.html deleted file mode 100644 index 4983b0e7f8..0000000000 --- a/CodenameOne/src/com/codename1/ui/html/package.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - -

- This package is deprecated and used only for legacy support, use the WebBrowser component - from the components package. - The HTML package allows rendering XHTML-MP 1.0 documents including WCSS support. -

-

-

- - diff --git a/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java b/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java index a15d650232..46ad11c759 100644 --- a/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java +++ b/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java @@ -901,9 +901,7 @@ public void removeLayoutComponent(Component component) { checkParent(parent); return .5f; }* - - /** - * Returns the alignment along the y axis. This specifies how + /// Returns the alignment along the y axis. This specifies how * the component would like to be aligned relative to other * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned diff --git a/CodenameOne/src/com/codename1/ui/layouts/package.html b/CodenameOne/src/com/codename1/ui/layouts/package.html deleted file mode 100644 index 5f21dce77c..0000000000 --- a/CodenameOne/src/com/codename1/ui/layouts/package.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - -

- Layout managers allow a {@link com.codename1.ui.Container} to - arrange its components by a set of rules that adapt to specific - densities (ppi - pixels per inch). A layout manager is an arranging algorithm encapsulated - by an abstract class implementation that places components absolutely based - on the "hints" received. -

-

Layout Managers that ship with Codename One

- -

- {@link com.codename1.ui.layouts.FlowLayout} is default layout manager, simple, flexible and with a few caveats. -

-Simple FlowLayout - -

- {@link com.codename1.ui.layouts.BorderLayout} is ubiquitous thru Codename One code. -

-Border Layout - -

- {@link com.codename1.ui.layouts.BorderLayout} can also behave differently based on the center behavior flag -

-Border Layout Center - -

- {@link com.codename1.ui.layouts.BoxLayout} Y axis is a the work-horse of component lists -

-Box Layout Y - -

- {@link com.codename1.ui.layouts.BoxLayout} X axis is a simpler replacement to flow layout and has grow/no grow - variants. -

-Box Layout X
-Box Layout X No Grow - -

- {@link com.codename1.ui.layouts.GridLayout} arranges elements in a grid where all elements have an equal size. It - can auto adapt - the column count. -

-Grid Layout 2x2 -Grid Layout autofit landscape - -

- {@link com.codename1.ui.table.TableLayout} is similar in many regards to HTML tables. Notice that its - in the com.codename1.ui.table package and not in this package. -

-TableLayout that grows the last column -TableLayout with complex constraints - -

- {@link com.codename1.ui.layouts.LayeredLayout} is unique in the sense that it is meant to costruct layers - and not the UI positions. It only lays out on the Z axis. -

-The X on this button was placed there using the layered layout code below - -

- {@link com.codename1.ui.layouts.GridBagLayout} was added to Codename One to ease the porting of Swing/AWT - applications. -

-Sample gridbag layout usage - -

- {@link com.codename1.ui.layouts.mig.MigLayout} is a popular 3rd party layout manager its Codename One - port is experimental. -

-MiG Layout - - - diff --git a/CodenameOne/src/com/codename1/ui/list/package.html b/CodenameOne/src/com/codename1/ui/list/package.html deleted file mode 100644 index 33a6813152..0000000000 --- a/CodenameOne/src/com/codename1/ui/list/package.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - -

- Lists are highly customizable and serve as the basis for {@link com.codename1.ui.ComboBox} and - other components (such as carousels etc) they employ a similar MVC approach to - Swing including the renderer pattern, notice that we strongly - discourage usage of lists...
{@link com.codename1.ui.list.ListCellRenderer} - allows us to customize the appearance of a list entry, it works as a - "rubber stamp" by drawing the rendered component and discarding its state thus - allowing very large lists with very little component state overhead. -

-

- {@link com.codename1.ui.list.ListModel} allows us to represent the underlying - data structure for the {@link com.codename1.ui.List}/{@link com.codename1.ui.ComboBox} - without requiring all the data to reside in memory or in a specific structure. - This allows a model to represent a data source of any type, coupled with the renderer the - data source can be returned in an internal representation state and still be rendered - properly to the screen. -

- - diff --git a/CodenameOne/src/com/codename1/ui/package.html b/CodenameOne/src/com/codename1/ui/package.html deleted file mode 100644 index 760c0f0ee9..0000000000 --- a/CodenameOne/src/com/codename1/ui/package.html +++ /dev/null @@ -1,459 +0,0 @@ - - - - - - - -

- Main widget package containing the component/container "composite" similar - both in terminology and design to Swing/AWT. -

-

Component/Container Relationship

-

- Containers can be nested one within the other to form elaborate UI's. Containers use - {@link com.codename1.ui.layouts} to arrange the components within. This is important - as it allows a container can adapt to changing resolution, DPI, orientation, font size etc. -

-Component/Container Relationship Diagram -

- A container doesn't implicitly reflow its elements and in that regard follows the direction of AWT/Swing. As - a result the layout can be animated to create a flowing effect for UI changes. This also provides improved - performance as a bonus. See this sample of {@code Container} animation: -

- - -

- You can learn more about layout managers {@link com.codename1.ui.layouts here} and about - event handling {@link com.codename1.ui.events here}. -

- -

Component Gallery

-

- The component gallery below isn't complete or exhaustive but it should give you a sense of the - types of widgets available within Codename One in a glance. -

- - -
-

AutoCompleteTextField

- - Simple usage of auto complete - -
{@link com.codename1.ui.AutoCompleteTextField} provides suggestions as you type into the text - field -
-
- -
-

BrowserComponent

- - Simple usage of BrowserComponent - -
{@link com.codename1.ui.BrowserComponent} allows us to embed an OS native browser into the app and - connect to its JavaScript runtime! -
-
- -
-

Button

- - Simple Button - -
{@link com.codename1.ui.Button} allows us to bind events to a click
-
- -
-

Link Button

- - Hyperlink Button - -
{@link com.codename1.ui.Button} can also be used as a hyperlink
-
- -
-

Calendar

- - Default calendar look - -
{@link com.codename1.ui.Calendar} presents a visual date picker. Notice that we recommend using - the - {@link com.codename1.ui.spinner.Picker} class which is superior when running on the device for most use cases. -
-
- - -
-

CheckBox

- - Sample usage of CheckBox/RadioButton/ButtonGroup - -
{@link com.codename1.ui.CheckBox} provides a check flag to tick on/off. - {@link com.codename1.ui.RadioButton} provides an exclusive check marking that only applies to one radio within - the group. - Both can also appear as toggle buttons -
-
- -
-

ComboBox

- - Rich ComboBox - -
{@link com.codename1.ui.ComboBox} is a list with a single visible entry that can popup the full - list. Notice that we recommend using the - {@link com.codename1.ui.spinner.Picker} class which is superior when running on the device for most use cases -
-
- -
-

Command

- - Simple usage of Toolbar - -
{@link com.codename1.ui.Command} & {@link com.codename1.ui.Toolbar} provide deep customization - of the title area and allow us to place elements in the side menu (hamburger), overflow menu etc. -
-
- -
-

ComponentGroup

- - Sample ComponentGroup Grouping - -
{@link com.codename1.ui.ComponentGroup} allows us to group components together in a a group and - manipulate - their UIID's. -
-
- -
-

Dialog

- - Dialog South - -
{@link com.codename1.ui.Dialog} allows us to notify/ask the user in a modal/modless way.
-
- -
-

InfiniteContainer

- - Sample usage of infinite scroll adapter - -
{@link com.codename1.ui.InfiniteContainer} & {@link - com.codename1.components.InfiniteScrollAdapter} - implement a {@link com.codename1.ui.Container} that can dynamically fetch more data -
-
- -
-

Label

- - Label text positioning - -
{@link com.codename1.ui.Label} displays text and/or icons to the user
-
- -
-

List

- - Sample of using the generic list cell renderer - -
{@link com.codename1.ui.List} a list of items, this is a rather elaborate component to work with! - We often - recommend just using {@link com.codename1.ui.Container}, {@link com.codename1.ui.InfiniteContainer} or - {@link com.codename1.components.InfiniteScrollAdapter} -
-
- -
-

MultiList

- - MultiList and model in action - -
{@link com.codename1.ui.list.MultiList} a list that is a bit simpler to work with than List {@link - com.codename1.ui.List} although - our recommendation to use something else still applies -
-
- -
-

Slider

- - Sample Slider - -
{@link com.codename1.ui.Slider} allows us to indicate progress or allows the user to drag a bar to - indicate - volume (as in quantity) -
-
- -
-

SwipeableContainer

- - Swipeable Container - -
{@link com.codename1.ui.SwipeableContainer} enables side swipe gesture to expose additional - functionality -
-
- - -
-

Tabs

- - Simple usage of Tabs - -
{@link com.codename1.ui.Tabs} places components/containers into tabbable entries, allows swiping - between choices thru touch -
-
- -
-

Carousel

- - Tabs carousel page 1 - -
{@link com.codename1.ui.Tabs} can also be used as a swipe carousel
-
- -
-

TextArea/Field

- - Text field input sample - -
{@link com.codename1.ui.TextArea} & {@link com.codename1.ui.TextField} allow for user input - via - the keyboard (virtual or otherwise) -
-
- -
-

TextComponent

- - Text field input sample - -
{@link com.codename1.ui.TextComponent} & {@link com.codename1.ui.PickerComponent} wrap the - text field and picker respectively and adapt them better to iOS/Android conventions -
-
- -
-

Table

- - Table with customize cells using the pinstripe effect - -
{@link com.codename1.ui.table.Table} displays optionally editable tabular data to the user
-
- -
-

Tree

- - Tree with XML data - -
{@link com.codename1.ui.tree.Tree} displays data in a tree like hierarchy
-
- -
-

ChartComponent

- - Chart Component - -
{@link com.codename1.charts.ChartComponent} can embed a wide range of visualization aids and - animations into your app -
-
- -
-

ImageViewer

- - Image viewer with dynamic URL fetching model - -
{@link com.codename1.components.ImageViewer} swipe, pinch to zoom and pan images
-
- - -
-

InfiniteProgress

- - InfiniteProgress - -
{@link com.codename1.components.InfiniteProgress} provides a constantly spinning component
-
- -
-

InteractionDialog

- - InteractionDialog Sample - -
{@link com.codename1.components.InteractionDialog} an "always on top" {@link - com.codename1.ui.Dialog} -
-
- -
-

MediaPlayer

- - Media player sample - -
{@link com.codename1.components.MediaPlayer} allows playing media including video coupled with the - {@link com.codename1.media.MediaManager} -
-
- -
-

MultiButton

- - MultiButton usages Sample - -
{@link com.codename1.components.MultiButton} is much more than a button
-
- -
-

OnOffSwitch

- - The looks of the on-off switch - -
{@link com.codename1.components.OnOffSwitch} allows us to toggle a state similar to the {@link - com.codename1.ui.CheckBox} - but with a more modern look -
-
- -
-

ShareButton

- - Share on the device - -
{@link com.codename1.components.ShareButton} provides native "social share" functionality
-
- -
-

SpanLabel

- - SpanLabel Sample - -
{@link com.codename1.components.SpanLabel} a text label that "seamlessly" breaks lines
-
- -
-

SpanButton

- - SpanButton Sample - -
{@link com.codename1.components.SpanButton} a button that "seamlessly" breaks lines
-
- -
-

Picker (Date)

- - Android native date picker - -
{@link com.codename1.ui.spinner.Picker} allows us to show an OS native picker UI (Date Picker) -
-
- -
-

Picker (Time)

- - Android native time picker - -
{@link com.codename1.ui.spinner.Picker} allows us to show an OS native picker UI (Time Picker) -
-
- -
-

ToastBar

- - Android native time picker - -
{@link com.codename1.components.ToastBar} shows a non-obtrusive notice on the bottom of the {@code - Form} -
-
- - -
-

SignatureComponent

- - Signature Component - -
{@link com.codename1.components.SignatureComponent} shows a dialog that allows the user to "sign" - using the touch screen -
-
- -
-

Accordion

- - Accordion Component - -
{@link com.codename1.components.Accordion} displays collapsible content panels
-
- -
-

FloatingHint

- - FloatingHint Component - -
{@link com.codename1.components.FloatingHint} animates the text field hint into a label on top of - the text field and visa versa -
-
- -
-

FloatingActionButton

- - FloatingActionButton Component - -
{@link com.codename1.components.FloatingActionButton} hovers over the UI presenting a default - action -
-
- - - diff --git a/CodenameOne/src/com/codename1/ui/painter/package.html b/CodenameOne/src/com/codename1/ui/painter/package.html deleted file mode 100644 index 8c238e121e..0000000000 --- a/CodenameOne/src/com/codename1/ui/painter/package.html +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - -

- {@link com.codename1.ui.Painter} allows us to draw arbitrary elements - of graphics from plain/scaled/tiled images to gradients and pretty - much any form of graphic drawing we can imagine. Painters are - "hooked" into the core of the API thus allowing us to customize - every aspect of it. See {@link com.codename1.ui.Component} and - {@link com.codename1.ui.Form}. -

- - diff --git a/CodenameOne/src/com/codename1/ui/plaf/package.html b/CodenameOne/src/com/codename1/ui/plaf/package.html deleted file mode 100644 index d3b005b12c..0000000000 --- a/CodenameOne/src/com/codename1/ui/plaf/package.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - -

- Look of the application can be fully customized via this package, it represents - a rendering layer that can be plugged in separately in runtime and themed to - provide any custom look. Unlike the Swing PLAF this layer does not support any - aspect of "feel" as in event handling etc. since these aspects would require a - much bigger and more elaborate layer unfit for small device OTA delivery. -

-

- Sizes of components are also calculated by the {@link com.codename1.ui.plaf.LookAndFeel} - since the size is very much affected by the look of the application e.g. the thickness - of the border and the font sizes. -

- - diff --git a/CodenameOne/src/com/codename1/ui/scene/package.html b/CodenameOne/src/com/codename1/ui/scene/package.html deleted file mode 100644 index edfdbeed9a..0000000000 --- a/CodenameOne/src/com/codename1/ui/scene/package.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - -

- This package provides a light-weight scene graph for Codename One. It is marked deprecated because it is - for internal use only. -

- - diff --git a/CodenameOne/src/com/codename1/ui/spinner/package.html b/CodenameOne/src/com/codename1/ui/spinner/package.html deleted file mode 100644 index 41cee0babb..0000000000 --- a/CodenameOne/src/com/codename1/ui/spinner/package.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - -

- Spinners allows picking of simple sequential values similarly to combo boxes but of a much wider value set. - They are mostly designed for picking dates, numbers or hours of the day. -

- - diff --git a/CodenameOne/src/com/codename1/ui/table/package.html b/CodenameOne/src/com/codename1/ui/table/package.html deleted file mode 100644 index c7d012d3db..0000000000 --- a/CodenameOne/src/com/codename1/ui/table/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -

- Table component for editing and viewing tabular data and arranging Codename One components in a tabular form -

- - diff --git a/CodenameOne/src/com/codename1/ui/tree/package.html b/CodenameOne/src/com/codename1/ui/tree/package.html deleted file mode 100644 index 071acc71a6..0000000000 --- a/CodenameOne/src/com/codename1/ui/tree/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -

- Tree component for displaying hierarchy based information and its related classes -

- - diff --git a/CodenameOne/src/com/codename1/ui/util/package.html b/CodenameOne/src/com/codename1/ui/util/package.html deleted file mode 100644 index 611f6e3dda..0000000000 --- a/CodenameOne/src/com/codename1/ui/util/package.html +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - -

- Utility features that are either too domain specific or don't "fit" into any - other packages including the Resource file format loading API. -

- - diff --git a/CodenameOne/src/com/codename1/ui/validation/package.html b/CodenameOne/src/com/codename1/ui/validation/package.html deleted file mode 100644 index 078a93936e..0000000000 --- a/CodenameOne/src/com/codename1/ui/validation/package.html +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - -

- The validation framework allows us to mark invalid input in text components and disable components - in the case of invalid input -

- - diff --git a/CodenameOne/src/com/codename1/util/Base64.java b/CodenameOne/src/com/codename1/util/Base64.java index 4e042537bd..e4e6b6b740 100644 --- a/CodenameOne/src/com/codename1/util/Base64.java +++ b/CodenameOne/src/com/codename1/util/Base64.java @@ -92,14 +92,19 @@ public static byte[] decode(byte[] in, int len) { return trimmed; } - /** - * Decodes Base64 input into a caller-provided output buffer. - * - * @param in Base64 bytes - * @param len bytes from {@code in} to decode - * @param out destination buffer - * @return decoded length, or {@code -1} for invalid Base64 - */ + /// Decodes Base64 input into a caller-provided output buffer. + /// + /// #### Parameters + /// + /// - `in`: Base64 bytes + /// + /// - `len`: bytes from `in` to decode + /// + /// - `out`: destination buffer + /// + /// #### Returns + /// + /// decoded length, or `-1` for invalid Base64 @DisableDebugInfo @DisableNullChecksAndArrayBoundsChecks public static int decode(byte[] in, int len, byte[] out) { @@ -342,13 +347,17 @@ public static String encodeNoNewline(byte[] in) { return com.codename1.util.StringUtil.newString(out, 0, outputLength); } - /** - * Encodes input into a caller-provided output buffer without line breaks. - * - * @param in input bytes - * @param out destination buffer - * @return number of bytes written to {@code out} - */ + /// Encodes input into a caller-provided output buffer without line breaks. + /// + /// #### Parameters + /// + /// - `in`: input bytes + /// + /// - `out`: destination buffer + /// + /// #### Returns + /// + /// number of bytes written to `out` @DisableDebugInfo @DisableNullChecksAndArrayBoundsChecks public static int encodeNoNewline(byte[] in, byte[] out) { diff --git a/CodenameOne/src/com/codename1/util/package.html b/CodenameOne/src/com/codename1/util/package.html deleted file mode 100644 index fa7b1ee3b7..0000000000 --- a/CodenameOne/src/com/codename1/util/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -

- General utilities classes -

- - diff --git a/CodenameOne/src/com/codename1/util/regex/package.html b/CodenameOne/src/com/codename1/util/regex/package.html deleted file mode 100644 index 2746302a90..0000000000 --- a/CodenameOne/src/com/codename1/util/regex/package.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - -

- A simple regular expression API that is portable across all platforms -

- - diff --git a/CodenameOne/src/com/codename1/xml/package.html b/CodenameOne/src/com/codename1/xml/package.html deleted file mode 100644 index 0f6976c259..0000000000 --- a/CodenameOne/src/com/codename1/xml/package.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - -

- The XML package allows parsing XML documents into DOM objects. -

-

-

- - From 90634114ee389134adfe922ec52bfcce9880b498 Mon Sep 17 00:00:00 2001 From: liannacasper <67953602+liannacasper@users.noreply.github.com> Date: Tue, 14 Apr 2026 21:44:32 +0300 Subject: [PATCH 9/9] Fix broken comment block in GroupLayout --- CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java b/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java index 46ad11c759..6f3838dd43 100644 --- a/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java +++ b/CodenameOne/src/com/codename1/ui/layouts/GroupLayout.java @@ -900,8 +900,8 @@ public void removeLayoutComponent(Component component) { /*public float getLayoutAlignmentX(Container parent) { checkParent(parent); return .5f; - }* - /// Returns the alignment along the y axis. This specifies how + }*/ + /* Returns the alignment along the y axis. This specifies how * the component would like to be aligned relative to other * components. The value should be a number between 0 and 1 * where 0 represents alignment along the origin, 1 is aligned