今日已更新 302 条资讯 | 累计 37551 条内容
关于我们

标签:#Java

找到 1192 篇相关文章

AI 资讯

Nylo: Building a Privacy-Minimized Analytics Layer Across Domains You Control

Most organizations do not operate a single website. A typical customer journey might move through: company.com ↓ docs.company.com ↓ company-academy.com ↓ company-checkout.com These properties may belong to the same organization, but browsers and analytics systems can treat each domain as a separate visitor and session. Cross-domain measurement is possible with major analytics platforms, but it normally ties the implementation to a specific vendor, transfers an existing measurement identifier through the destination URL, or depends on users authenticating. I built Nylo to explore another approach: Preserve pseudonymous continuity across domains an organization controls, without browser fingerprinting, third-party cookies, or requiring the visitor to log in. Nylo is not intended to identify a person. It is intended to answer a narrower question: Did the same pseudonymous browser journey continue from one authorized domain to another? What Nylo is Nylo consists of: A zero-dependency JavaScript client SDK A server-side event ingestion interface A pseudonymous identifier called a WaiTag A short-lived cross-domain token exchange DNS-based verification of participating domains Configurable event collection Storage adapters for different backend systems The core analytics SDK is available under the MIT License. Production commercial use of the cross-domain WTX-1 functionality uses a separate commercial license. Nylo is designed to function as an analytics collection and continuity layer. It can eventually send events to an existing warehouse or analytics platform rather than requiring organizations to replace their reporting stack. How continuity works Consider a visitor moving between two independently registered domains: Visitor opens site-a.com | v Nylo creates a pseudonymous WaiTag | v Visitor follows an authorized link | v A short-lived token is transferred | v site-b.com verifies the token | v Both events reference the same pseudonymous journey Before enabling cross-d

2026-08-06 原文 →
AI 资讯

Vercel vs Netlify vs Cloudflare Pages: Where Your Side Project Should Actually Live

For a side project, the short answer is: Cloudflare Pages if you want the cheapest ceiling and never think about bandwidth, Vercel if you're on Next.js and want the smoothest developer experience, Netlify if you want a mature all-in-one with forms and identity baked in. All three have a free tier that will host a hobby app fine. The differences that actually bite you show up later — when a post gets traffic, when your build gets slow, or when you outgrow static files and start running server code. I've deployed personal projects on all three over the last couple of years. Below is how I'd choose today, with the real trade-offs rather than the marketing version. What are you actually deploying? Before comparing platforms, be honest about your app, because it changes the answer more than any feature chart: Pure static site (docs, a marketing page, a SPA that talks to an external API): all three are excellent and free. The decision barely matters. Static frontend + a few serverless functions (a contact form handler, an auth callback, a small API): now runtime, cold starts, and function limits matter. A full framework app with server rendering (Next.js App Router, SvelteKit, Remix): now framework-specific adapters and edge/runtime compatibility matter a lot. The takeaway: pick based on your heaviest workload, not your current one — migrating hosts after you've wired up auth and functions is the annoying part. How do the free tiers really compare? This is where these platforms differ the most for hobby use. The headline distinction, as of mid-2026: Cloudflare Pages does not meter bandwidth on its free plan , while Vercel and Netlify both count usage (bandwidth, function invocations, build minutes) against free-tier limits and will ask you to upgrade — or throttle — when you cross them. Concern Vercel (Hobby) Netlify (Free) Cloudflare Pages (Free) Bandwidth Metered, capped Metered, capped Unlimited Build minutes Limited Limited Limited (per-month build count) Serverless/e

2026-08-06 原文 →
AI 资讯

A Privacy-First Browser Workflow for AI Photo Editing

AI photo editors look simple from the outside: upload an image, describe a change, and download the result. The hard part is everything around the model call. If you are building or evaluating a browser-based image editor, the workflow needs to protect the original file, reject bad inputs early, make retries safe, and help the user compare the result with the source. This article walks through a small implementation pattern that does that without turning the UI into a complex desktop editor. 1. Validate the image before upload Do not rely on the file extension. Check the MIME type, file size, and whether the browser can actually decode the image. const ACCEPTED_TYPES = new Set ([ " image/jpeg " , " image/png " , " image/webp " , ]); async function validateImage ( file ) { if ( ! ACCEPTED_TYPES . has ( file . type )) { throw new Error ( " Use a JPG, PNG, or WebP image. " ); } const maxBytes = 10 * 1024 * 1024 ; if ( file . size > maxBytes ) { throw new Error ( " The image must be smaller than 10 MB. " ); } const bitmap = await createImageBitmap ( file ); const dimensions = { width : bitmap . width , height : bitmap . height }; bitmap . close (); if ( dimensions . width < 64 || dimensions . height < 64 ) { throw new Error ( " The image is too small for a useful edit. " ); } return dimensions ; } This catches renamed files, broken images, and tiny inputs before they consume bandwidth or model credits. 2. Treat the prompt as a single edit contract Open-ended chat is useful, but it can make image editing unpredictable. A clearer UI asks for one concrete change at a time: remove the person on the right; replace the background with a plain white wall; repair the crease across the top-left corner; extend the image to a 16:9 frame. The request object should preserve that intent without mixing it with UI state: function buildEditRequest ( file , prompt , options = {}) { const normalizedPrompt = prompt . trim (). replace ( / \s +/g , " " ); if ( normalizedPrompt . length < 5 )

2026-08-06 原文 →
AI 资讯

Advice

Hi guys, I'm a 2026 fresher. I'm confused about choosing between Java, Python, .NET, and MERN. Is Full Stack still worth learning with AI growing so fast? Can a skilled fresher still get a job? Any advice?

2026-08-06 原文 →
AI 资讯

TypeScript Strict Null Checks in 2026: Real-World Patterns for Handling `undefined` Without the Noise

TypeScript Strict Null Checks in 2026: Real-World Patterns for Handling undefined Without the Noise This article was written with the assistance of AI, under human supervision and review. Most TypeScript null safety problems stem from teams treating strictNullChecks as a boolean toggle instead of a design constraint. The compiler flag eliminates an entire class of production bugs, but codebases that flip it on without adjusting their patterns end up drowning in type assertions and optional chaining operators. The result is worse than the original false confidence wrapped in noise. The fundamental issue is that JavaScript conflates absence and failure. A missing property, an API error, and an uninitialized variable all return undefined or null , but they represent completely different failure modes. When teams enable strictNullChecks without encoding these distinctions into their types, the compiler forces them to handle every potential undefined the same way. That leads to defensive checks that obscure intent and catch nothing of value. The correct approach treats null safety as a type design problem. Discriminated unions encode why a value is missing. Branded types prove non-nullability at the boundary. Type guards narrow only when the business logic demands it. The patterns are simple, but they require understanding what the compiler is actually checking and what guarantees your code actually needs. This post covers the essential patterns teams need to write null-safe TypeScript in 2026 without the noise. Apply these in production and the difference will be immediate. Key Takeaways strictNullChecks eliminates runtime null errors only if your types encode why values are missing, not just that they might be missing. Discriminated unions outperform null returns for API responses because they force exhaustive handling of failure cases at compile time. Non-null assertions ( ! ) are acceptable at proven boundaries where external systems guarantee non-null values, but ne

2026-08-06 原文 →
AI 资讯

Debugging Node.js Like a Pro

Start with the Built-in Inspector Before reaching for external tools, remember Node.js has a built-in debugger. Run your script with --inspect and open chrome://inspect in Chrome to get a full DevTools experience: breakpoints, step-through, console, and even memory profiling. node --inspect app.js For a quick breakpoint without touching the browser, use --inspect-brk to pause on the first line. This is great for debugging startup issues. Use debugger Statements and Conditional Breakpoints Sometimes you need a breakpoint only when a condition is true. Instead of littering your code with if blocks, set a conditional breakpoint in DevTools. Right-click the line number, choose "Add conditional breakpoint," and enter an expression like user.id === 42 . For quick inline debugging, debugger; works but remember to remove it before committing. I often use it temporarily when I'm too lazy to open the DevTools UI. Log Like a Pro with util.inspect console.log of an object prints [object Object] which is useless. Use util.inspect with depth and colors to see nested structures clearly. const util = require ( ' util ' ); console . log ( util . inspect ( myObject , { showHidden : false , depth : null , colors : true })); Or in modern Node, you can use console.dir with { depth: null } for the same effect. Async Stack Traces: Don't Lose the Context Async errors are painful because stack traces often end at the event loop. Node 12+ gives you better async stack traces by default, but you can improve them further by using Error.captureStackTrace in your own error classes. class MyError extends Error { constructor ( message ) { super ( message ); Error . captureStackTrace ( this , MyError ); } } This makes the stack trace point to the caller, not the constructor. Handle Unhandled Rejections and Exceptions Silent failures are the worst. Set up global handlers to log errors properly and exit gracefully. process . on ( ' unhandledRejection ' , ( reason , promise ) => { console . error ( ' U

2026-08-06 原文 →
AI 资讯

Presentation: Automatically Retrofitting JIT Compilers

Laurence Tratt discusses yk, an open-source meta-tracing JIT compiler framework. He shares how to automatically speed up C-based language interpreters like Lua and MicroPython with minimal, non-invasive code changes. He explains the inner workings of tracing loops, optimizing compiled traces using developer hints, and managing complex deoptimization back to the interpreter. By Laurence Tratt

2026-08-05 原文 →
AI 资讯

Programmatic SEO with hreflang: One Joke, 17 Languages, Server-Rendered

People type 2+2 into Google. They type 9+10 . They type 7*8 when they can't remember whether it's 54 or 56. Each of those is a real, high-volume search query — and most of the results are identical calculator widgets. So when I built Wrongulator , a calculator that returns a confidently wrong answer on purpose, I had a question worth asking: what if every expression were its own page, ranking for the exact arithmetic people already search? That is programmatic SEO — generating a page per parameter instead of writing pages by hand. And doing it across 17 languages means programmatic SEO with hreflang, where each generated page also declares its 16 translated siblings. The trap is that most programmatic surfaces are thin, duplicative, and get buried by Google. This one isn't, for a specific reason: every page has a real, unique answer baked into the HTML before any JavaScript runs. This post is about how — and the honest costs nobody mentions. Why a Permalink Per Expression Is Even Possible A page per expression only works if /2+2 reproduces the same result for everyone, forever, with no database behind it. That property isn't free — it's the result of one design decision I cover in detail in why a viral toy must be wrong the same way every time : the wrong answer is a pure function of the expression, seeded by a stable hash, with no per-user state. The relevant consequence here is what that property unlocks for SEO. Because f("2+2") always returns the same wrong answer, the server can compute that answer on demand for any expression in the URL, with zero storage. There's no pages table, no CMS, no pre-generation job. A request for /64+5 runs the engine, gets 67 ("the only correct number"), and renders a complete page around it. The programmatic surface is, in effect, infinite — but it costs nothing to hold, because nothing is stored. The pure function is what makes thousands of unique pages possible without a database. That's the foundation. Everything below is about

2026-08-05 原文 →
AI 资讯

Can IP Geolocation Personalise Content with Node.js?

A visitor lands on a website and immediately sees prices in the wrong currency, content written for another region, and shipping information that does not apply to them. Nothing is technically broken, yet the experience feels poorly designed. For international websites, location can be a useful personalization signal. Instead of asking every visitor to manually select a country before displaying relevant information, developers can use IP based geographic data as an initial indication of where a request originates. That is where ip geolocation for content personalisation can become useful. The objective is not to identify a person. It is to make an otherwise anonymous visit more contextually relevant. How can location improve content personalisation? Location can influence many small decisions that collectively affect the user experience. An ecommerce website may display a local currency. A news publisher may surface regional stories. A software company may show country specific documentation or availability information. The process is relatively simple. A visitor sends a request to a website. The server obtains the request's public IP address. That IP is sent to a geolocation service. The response provides geographic information. The application then selects content according to predefined rules. The crucial part is the final step. Geolocation provides data, but business logic determines what the visitor actually sees. Which approaches can websites use? One approach is manual location selection. The user chooses their country or region from a menu. This is transparent and usually accurate because the user explicitly provides the information. However, it adds friction and may be forgotten during future visits. Browser based location is another option. It can provide more precise positioning, but it normally requires permission and is not always appropriate for simple content personalization. IP based geolocation sits between these approaches. It requires no location

2026-08-05 原文 →
AI 资讯

Building a 3D Product Configurator in Three.js — Lessons From 9 Client Deployments

Over the last year I shipped 9 production 3D configurators for polish manufacturers — pools, garage doors, saunas, pergolas, greenhouses, packaging, decorative lamps, terrace roofs, and light-boxes. Each one runs live on its own subdomain of my studio at grodev.pl . Some of the lessons were obvious in hindsight. Some cost me a weekend of debugging. Sharing the non-obvious ones here. 1. Draco compression is not optional for CAD-heavy models Manufacturers send you STEP or SolidWorks files exported to glTF . Raw output is 40–120 MB per variant. On 4G mobile that's a 20-second load with an empty white canvas. Draco compression brings that to 2–5 MB with no visible quality loss on product shots: import { GLTFLoader } from ' three/examples/jsm/loaders/GLTFLoader.js ' import { DRACOLoader } from ' three/examples/jsm/loaders/DRACOLoader.js ' const dracoLoader = new DRACOLoader () dracoLoader . setDecoderPath ( ' /draco/ ' ) // self-hosted, don't use CDN const loader = new GLTFLoader () loader . setDRACOLoader ( dracoLoader ) loader . load ( ' /models/pool-3.5m.glb ' , ( gltf ) => { scene . add ( gltf . scene ) }) Self-host the decoder — Google's CDN version added ~600 ms to first paint in my measurements. Copy node_modules/three/examples/jsm/libs/draco/ to your public/ folder. Tooling: gltf-pipeline -i model.glb -o model.draco.glb --draco.compressionLevel 10 2. Instancing beats individual meshes past ~200 objects A pergola with 40 louvres × 3 tilt positions × user color picker = 120 meshes updating on every frame. Naive approach tanks FPS to 12 on mid-range phones. InstancedMesh batches identical geometry into one draw call: const geo = new THREE . BoxGeometry ( 1 , 0.05 , 3 ) const mat = new THREE . MeshStandardMaterial () const louvres = new THREE . InstancedMesh ( geo , mat , 40 ) const dummy = new THREE . Object3D () for ( let i = 0 ; i < 40 ; i ++ ) { dummy . position . set ( 0 , 0 , i * 0.15 ) dummy . rotation . x = userTilt // update per frame is fine dummy . updateM

2026-08-05 原文 →
AI 资讯

I built a short-code marketplace with zero npm dependencies (Node.js 22, no framework)

I've been going back and forth on whether to share this — it's a pretty niche idea, and I wasn't sure if it's clever or just weird. But here's the technical side of it, which I figure this crowd might actually appreciate regardless. What I built: claimo.me — you claim a short code (2-4 letters, or a custom name) for a one-time fee, no subscription, permanently yours. Each code is configurable as a redirect link, a QR code, or a small profile card. There's also a "Claimo Map" — every possible code is a clickable pixel you can browse, inspired by the old Million Dollar Homepage. The part I actually want to talk about here: it's zero-dependency. No Express, no ORM, no build step — just Node.js 22+'s built-in http module and the new built-in node:sqlite. I wanted to see how far "just the standard library" actually gets you for something real — payments (Stripe), admin moderation, rate limiting, a live interactive map UI, the works. Some things that surprised me building it this way: node:sqlite's DatabaseSync is genuinely pleasant to use, but it's missing conveniences like better-sqlite3's .transaction() helper — I ended up writing a small manual BEGIN/COMMIT/ROLLBACK wrapper. Routing without a framework is maybe 40 lines of code and I stopped missing Express within a day. The real cost isn't runtime performance, it's losing the ecosystem — anything I'd normally npm install for free (input validation, rate limiting, even basic templating) I had to hand-roll. Some of that was genuinely good for me, some of it I'd reconsider on a bigger project. Business side, since half of you will ask: it's a real registered business, payments go through Stripe only (I never touch card data), no crypto, nothing weird. The paid tiers fund keeping a free short-link tier alive too. Honestly — is the zero-dependency thing a genuinely good call for a real production app, or am I just going to regret it in a year? And separately: does "own a short code" as a product idea make any sense to you

2026-08-05 原文 →
AI 资讯

Building an Editable 3D Indoor Map in the Browser

Indoor maps are often treated as a rendering problem: take a floor plan, extrude a few walls, and display the result. That is useful for a viewer, but it breaks down when a team needs to edit a real space, place assets, or hand the result to another application. We are building KiMap around a different boundary: turn a floor plan into an editable indoor scene in the browser, then keep the resulting structure useful for an SDK consumer. Why a floor plan is not enough A production indoor workflow needs more than a textured image on a plane. At minimum, the editor has to preserve the relationships between walls, floors, rooms, openings, and the objects placed in the space. Those relationships determine whether the result can later support navigation, facility workflows, a digital twin, or a custom web experience. That is why the current KiMap workflow starts with structure. You can define the indoor geometry, inspect it in 2D and 3D, and keep editing instead of committing to a static export too early. The browser editor boundary The editor is built with React and Three.js. The goal is not to replace every DCC tool. It is to make the early spatial workflow accessible to teams that need to test an indoor experience before investing in a full custom pipeline. The parts we are concentrating on are: editable floor-plan structure and bounded spaces 2D and 3D scene inspection in the same workflow reusable 3D furniture and local asset handling saving an indoor project without dropping the referenced model data a path toward SDK-oriented rendering and integration The last point matters. A scene that looks correct in an editor is not automatically useful to an application. We want the data boundary to be explicit enough that an SDK consumer can load the geometry and assets without rebuilding the scene from scratch. What we are testing next KiMap is in free early access. The most useful feedback is not generic interest; it is a concrete blocker from someone building an indoor-nav

2026-08-05 原文 →
AI 资讯

Environment Variables the Safe Way

Environment Variables the Safe Way Environment variables are the standard way to configure applications without hardcoding secrets or environment-specific details. But they're easy to misuse. I've seen API keys committed to repos, configs that crash when a variable is missing, and defaults that silently override production settings. Here's how I handle them safely. Never Commit Secrets The most important rule: never put real secrets in your code or commit them to version control. That includes .env files. Add .env to your .gitignore immediately. If you're using a framework like Laravel or a tool like Vite, the default .env.example is your friend. Commit that, but never the real one. For local development, you can generate a .env from the example and fill in your own values. For production, set variables through your hosting provider's dashboard or a secrets manager like AWS Secrets Manager or HashiCorp Vault. Read Variables Explicitly Don't access process.env directly all over your codebase. Instead, centralize your configuration. Create a config.js (or config.ts ) that reads and validates all the variables you need. // config.js const required = [ ' DATABASE_URL ' , ' JWT_SECRET ' , ' PORT ' ]; const missing = required . filter ( key => ! process . env [ key ]); if ( missing . length ) { throw new Error ( `Missing required environment variables: ${ missing . join ( ' , ' )} ` ); } module . exports = { databaseUrl : process . env . DATABASE_URL , jwtSecret : process . env . JWT_SECRET , port : parseInt ( process . env . PORT , 10 ) || 3000 , }; Now your app imports config and uses config.port . This has several benefits: Fail fast: if a required variable is missing, the app crashes at startup, not later when you try to use it. Type safety: you can parse and validate values once. Easy to mock in tests. Use Defaults Carefully Defaults are convenient, but they can hide problems. For example, if you default PORT to 3000 in production, you might accidentally run on the w

2026-08-05 原文 →
开发者

I got tired of mocking Date, so I built a TimeProvider for TypeScript

Every (or at least a lot of) project seems to have code like this somewhere: if (user.subscriptionEndsAt < new Date()) { // ... } There's nothing wrong with it... until you have to test it. Then you end up freezing time, mocking Date, enabling fake timers, remembering to restore them afterwards, and hoping another test didn't leave the clock in a weird state. While Jest's and Vitest's fake timers are great tools, they always felt like they were solving the problem from the outside by patching global APIs. I wanted to try something different. Time is a dependency When you think about it, the current time isn't much different from a database or an HTTP client. Your business logic depends on it, but it doesn't have to know where it comes from. Instead of writing this: const now = new Date(); what if we wrote this? const now = timeProvider.now(); Suddenly, testing becomes boring—in the best possible way. You don't need global fake timers anymore. You just pass a different implementation. .NET had the same idea While looking into this, I discovered that .NET 8 introduced a TimeProvider abstraction. Seeing that was reassuring. It suggested I wasn't the only one who felt that "current time" deserved to be treated as a real dependency. I didn't want to copy the .NET API, but I did like the underlying idea. So I started building a version that felt natural in the TypeScript ecosystem. It grew beyond a clock At first I only wanted to replace new Date(). Then I realized the same issue exists with setTimeout, setInterval, performance measurements, and a few other APIs. They all depend on the environment's notion of time. So the library slowly became an abstraction around all of those instead of just "what time is it?". Is this actually useful? That's the part I'm still curious about. In the projects I've worked on, I prefer injecting time over patching globals during tests. Maybe other teams have reached the same conclusion. Maybe everyone is perfectly happy with fake timers an

2026-08-05 原文 →
AI 资讯

Four things that surprised me running Python in the browser

I built a debugging-practice site where student code runs entirely in the browser . Python via Pyodide , JavaScript in a worker. No server executes anything. No execution bill, no queue, no sandbox to maintain. But four things bit me hard. 1. Your arguments aren't Python objects Pass a JS object into Python and you get this: TypeError: 'pyodide.ffi.JsProxy' object is not subscriptable It's not a dict . It's a live view of the JS object, and it supports neither obj[key] nor .get() . Convert explicitly: const pyArgs = input . map (( arg ) => pyodide . toPy ( arg )); const result = fn (... pyArgs ); 2. null is not None This one passed my entire test suite while being broken in production. pyodide . toPy ( null ) check result type(v) JsNull bool(v) False ✅ falsy, as expected v is None False ❌ the surprise It's falsy, so truthiness checks work fine. But is None fails — which was exactly what my code was checking. Why my tests missed it: the harness used json.loads . The app used toPy . Different conversion paths, different answers. If you need a real None , create it in Python. Don't pass one across. 3. sys.settrace is a free step debugger Want to show users their code running line by line? Python basically hands it to you: def _tracer ( frame , event , arg ): if frame . f_code . co_name != target : return None # skip library frames if event == " line " : steps . append ({ " line " : frame . f_lineno , " locals " : dict ( frame . f_locals ), }) return _tracer Two things this naive version gets wrong: Add a step cap. A tight loop generates steps faster than it burns a 5-second timeout. You need both guards. Handle exception . During unwinding, the return event still fires with arg=None . Miss it and your trace says "returned None" for code that crashed. 4. Your snapshots are lying A user screenshot exposed this one. Every step in the trace showed the final state of a list. Step 1 included mutations that hadn't happened yet. tracing: nums = []; nums.append(1); nums.append(

2026-08-05 原文 →
AI 资讯

Browser vs Node — Where the Event Loop Actually Diverges (Part 2/3)

In part 1, we built the shared mental model: call stack, microtask queue, macrotask queue, and the rule that microtasks fully drain before the next macrotask runs. That model is spec-level JavaScript behavior — but it's not the whole story once you actually run code. The event loop isn't part of the JS language spec. It's part of the host environment — the browser or Node — and each one implements it differently around that shared core. This is the post most "event loop" explainers skip, because it means going past the diagram and into how each runtime is actually built. The browser: event loop meets rendering In a browser, the event loop isn't just juggling callbacks — it's also responsible for keeping the page visually responsive. That means rendering has to get a turn too, and the browser has to decide when . Here's the roughly accurate sequence per loop iteration: Execute one macrotask (a click handler, a setTimeout callback, a network event, whatever's next in the queue) Drain the entire microtask queue Maybe render a frame — the browser doesn't render after every single task; it tries to hit ~60fps and will batch work between paints Go back to step 1 The "maybe render" part is where two APIs come in that don't exist in Node at all: requestAnimationFrame(callback) — schedules a callback to run right before the next repaint. It's not a macrotask or microtask in the queue sense — it's tied directly to the rendering pipeline. Use it for anything visual (animations, DOM measurements) instead of setTimeout , because it's synced to when the browser is actually about to paint, not an arbitrary delay. requestIdleCallback(callback) — schedules a callback to run when the browser is idle, after layout and paint, with a deadline. Meant for low-priority work you don't want competing with rendering — analytics, prefetching, non-urgent DOM updates. Here's the key interaction that's easy to miss: microtasks can starve rendering. If a promise chain keeps queueing more microtask

2026-08-05 原文 →
AI 资讯

A Lightweight Rich Text Component Without a Web View

PR #5421 adds RichTextComponent , a read-only component for formatted application text. It supports headings, inline styles, lists, links, and images without embedding a web view. What is Codename One? Codename One is an open-source framework for building native iOS, Android, desktop, and web apps from a single Java or Kotlin codebase. Learn more at codenameone.com . A SpanLabel applies one style to wrapped text. A BrowserComponent renders a complete web page. RichTextComponent covers formatted document content between those two cases and participates in ordinary Codename One layout. Rich text inside a scrollable container A common screen mixes formatted text with buttons, images, forms, and other Codename One components inside one scrollable container. A BrowserComponent is a poor fit for that layout because it owns a rectangular native surface and its own page viewport. The browser's document height does not naturally become the height of a child inside the parent Codename One layout. RichTextComponent measures wrapped runs for the width it receives and reports the corresponding height. In the default SizeMode.SHRINK , it behaves like a SpanLabel : the parent container scrolls the rich text together with the surrounding components. SizeMode.SCROLL is available when the rich text should keep an assigned height and scroll its own content. The read-only view and editor agree on paragraph attributes, inline styles, links, image runs, and wrapping because they do not maintain competing renderers. Supply the format you already have HTML is not the only input: RichTextComponent view = new RichTextComponent (); view . setMarkdown ( "# Trip summary\n\n" + "Departs **09:40**, arrives *11:15*. " + "See the [itinerary](app://itinerary).\n\n" + "- Window seat\n" + "- Carry-on only" ); form . add ( view ); setContent(...) accepts RichTextFormat.HTML , MARKDOWN , ASCIIDOC , or RTF . The model covers headings, emphasis, inline code, links, images, lists, quotes, literal blocks, p

2026-08-04 原文 →