问:
fastest way to convert two-bit number to low-memory representation
I have a 56-bit number with potentially two set bits, e.g., 00000000 00000000 00000000 00000000 00000000 00000000 00000011. In other words, two bits are distributed among 56 bits, so that we have bin(56,2)=1540 possible permutations.

I now look for a loss-free mapping of such an 56 bit number to an 11-bit number that can carry 2048 and therefore also 1540. Knowing the structure, this 11-bit number is enough to store the value of my low-density (of ones) 56 bit number.

I want to maximize performance (this function should run millions or even billions of times per second if possible). So far, I only came up with some loop:

```<code>int inputNumber = 24; // 11000
int bitMask = 1;
int bit1 = 0, bit2 = 0;
for(int n = 0; n < 54; ++n, bitMask *= 2)
{
    if((inputNumber & bitMask) != 0)
    {
        if(bit1 != 0)
            bit1 = n;
        else
        {
            bit2 = n;
            break;
        }
    }
}
</code>```

and using these two bits, I can easily generate some 1540 max number.

But is there no faster version than using such a loop?

答:
Most ISAs have hardware support for a bit-scan instruction that finds the position of a set bit.  Use that instead of a naive loop or bithack for any architecture where you care about this running fast.  https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious has some tricks that are better than nothing, but those are all still much worse than a single efficient asm instruction.

But ISO C++ doesn't portably expose clz/ctz operations; it's only available via intrinsics / builtins for various implementations.  (And the x86 intrinsincs have quirks for all-zero input, corresponding to the asm instruction behaviour).

For some ISAs, it's a count-leading-zeros giving you 31 - highbit_index.  For others, it's a CTZ count trailing zeros operation, giving you the index of the low bit.  x86 has both.  (And its high-bit finder actually directly finds the high-bit index, not a leading-zero count, unless you use BMI1 lzcnt instead of traditional bsr)  https://en.wikipedia.org/wiki/Find_first_set has a table of what different ISAs have.

GCC portably provides __builtin_clz and __builtin_ctz; on ISAs without hardware support, they compile to a call to a helper functions.  See What is the fastest/most efficient way to find the highest set bit (msb) in an integer in C? and Implementation of __builtin_clz

(For 64-bit integers, you want the long long versions: like __builtin_ctzll GCC manual.)

If we only have a CLZ, use high=63-CLZ(n) and low= 63-CLZ((-n) & n) to isolate the low bit.  Note that x86's bsr instruction actually produces 63-CLZ(), i.e. the bit-index instead of the leading-zero count.  So 63-__builtin_clzll(n) can compile to a single instruction on x86; IIRC gcc does notice this.  Or 2 instructions if GCC uses an extra xor-zeroing to avoid the inconvenient false dependency.

If we only have CTZ, do low = CTZ(n) and high = CTZ(n & (n - 1)) to clear the lowest set bit.  (Leaving the high bit, assuming the number has exactly 2 set bits).

If we have both, low = CTZ(n) and high = 63-CLZ(n).  I'm not sure what GCC does on non-x86 ISAs where they aren't both available natively.  The GCC builtins are always available even when targeting HW that doesn't have it.  But the internal implementation can't use the above tricks because it doesn't know there are always exactly 2 bits set.

(I wrote out the full formulas; an earlier version of this answer had CLZ and CTZ reversed in this part.  I find that happens to me easily, especially when I also have to keep track of x86's bsr and bsr (bitscan reverse and forward) and remember that those are leading and trailing, respectively.)

So if you just use both CTZ and CLZ, you might end up with slow emulation for one of them.  Or fast emulation on ARM with rbit to bit-reverse for clz, which is 100% fine.

AVX512CD has SIMD VPLZCNTQ for 64-bit integers, so you could encode 2, 4, or 8x 64-bit integers in parallel with that on recent Intel CPUs.  For SSSE3 or AVX2, you can build a SIMD lzcnt by using pshufb _mm_shuffle_epi8 byte-shuffle as a 4-bit LUT and combining with _mm_max_epu8. There was a recent Q&A about this but I can't find it.  (It might have been for 16-bit integers only; wider requires more work.)

With this, a Skylake-X or Cascade Lake CPU could maybe compress 8x 64-bit integers per 2 or 3 clock cycles once you factor in the throughput cost of packing the results.  SIMD is certainly useful for packing 12-bit or 11-bit results into a contiguous bitstream, e.g. with variable-shift instructions, if that's what you want to do with the results.  At ~3 or 4GHz clock speed, that could maybe get you over 10 billion per clock with a single thread.  But only if the inputs come from contiguous memory.  Depending what you want to do with the results, it might cost a few more cycles to do more than just pack them down to 16-bit integers.  e.g. to pack into a bitstream.  But SIMD should be good for that with variable-shift instructions that can line up the 11 or 12 bits from each register into the right position to OR together after shuffling.

There's a tradeoff between coding efficiency and encode performance.  Using 12 bits for two 6-bit indices (of bit positions) is very simple both to compress and decompress, at least on hardware that has bit-scan instructions.

Or instead of bit-indices, one or both could be leading zero counts, so decoding would be (1ULL << 63) >> a.  1ULL>>63 is a fixed constant that you can actually right-shift, or the compiler could turn it into a left-shift of 1ULL << (63-a) which IIRC optimizes to 1 << (-a) in assembly for ISAs like x86 where shift instructions mask the shift count (look only at the low 6 bits).

Also, 2x 12 bits is a whole number of bytes, but 11 bits only gives you a whole number of bytes every 8 outputs, if you're packing them.  So indexing a bit-packed array is simpler.

0 is still a special case: maybe handle that by using all-ones bit-indices (i.e. index = bit 63, which is outside the low 56 bits).  On decode/decompress, you set the 2 bit positions (1ULL<<a) | (1ULL<<b) and then & mask to clear high bits.  Or bias your bit indices and have decode right shift by 1.

If we didn't have to handle zero then a modern x86 CPU could do 1 or 2 billion encodes per second if it didn't have to do anything else.  e.g. Skylake has 1 per clock throughput for bit-scan instructions and should be able to encode at 1 number per 2 clocks just bottlenecked on that.  (Or maybe better with SIMD).  With just 4 scalar instructions, we can get the low and high indices (64-bit tzcnt + bsr), shift by 6 bits, and OR together.1  Or on AMD, avoid bsr / bsf and manually do 63-lzcnt.

A branchy or branchless check for input == 0 to to set the final result to whatever hard-coded constant (like 63 , 63) should be cheap, though.

Compression on other ISAs like AArch64 is also cheap.  It has clz but not ctz.  Probably your best bet there is use an intrinsic for rbit to bit-reverse a number (so clz on the bit-reversed number directly gives you the bit-index of the low bit.  Which is now the high bit of the reversed version.)  Assuming rbit is as fast as add / sub, this is cheaper than using multiple instructions to clear the low bit.

If you really want 11 bits then you need to avoid the redundancy of 2x 6-bit being able to have either index larger than the other.  Like maybe have 6-bit a and 5-bit b, and have a<=b mean something special like b+=32.  I haven't thought this through fully.  You need to be able to encode 2 adjacent bits either near the top or bottom of the registers, or the 2 set bits could be as far apart as 28 bits, if we consider wrapping at the boundaries like a 56-bit rotate.

Melpomene's suggestion to isolate the low and high set bits might be useful as part of something else, but is only useful for encoding on targets where you only have one direction of bit-scan available, not both.  Even so, you wouldn't actually use both expressions.  Leading-zero count doesn't require you to isolate the low bit, you just need to clear it to get at the high bit.

Footnote 1:  decoding on x86 is also cheap:  x |= (1<<a) is 1 instruction: bts.  But many compilers have missed optimizations and don't notice this, instead actually shifting a 1.  bts reg, reg is 1 uop / 1 cycle latency on Intel since PPro, or sometimes 2 uops on AMD.  (Only the memory destination version is slow.)  https://agner.org/optimize/

Best encoding performance on AMD CPUs requires BMI1 tzcnt / lzcnt because bsr and bsf are slower (6 uops instead of 1 https://agner.org/optimize/).  On Ryzen, lzcnt is 1 uop, 1c latency, 4 per clock throughput.  But tzcnt is 2 uops.

With BMI1, the compiler could use blsr to clear the lowest set bit of a register (and copy it).  i.e. modern x86 has an instruction for dst = (SRC-1) bitwiseAND ( SRC ); that are single-uop on Intel but 2 uops on AMD.

But with lzcnt being more efficient than tzcnt on AMD Ryzen, probably the best asm for AMD doesn't use it.

Or maybe something like this (assuming exactly 2 bits, which apparently we can do).

(This asm is what you'd like to get your compiler to emit.  Don't actually use inline asm!)

```<code>Ryzen_encode_scalar:    ; input in RDI, output in EAX
   lzcnt    rcx, rdi       ; 63-high bit index
   tzcnt    rdx, rdi       ; low bit

   mov      eax, 63
   sub      eax, ecx

   shl      edx, 6
   or       eax, edx       ; (low_bit << 6) | high_bit

   ret                     ; goes away with inlining.
</code>```

Shifting the low bit-index balances the lengths of the critical path, allowing better instruction-level parallelism, if we need 63-CLZ for the high bit.

Throughput: 7 uops total, and no execution-unit bottlenecks.  So at 5 uops per clock pipeline width, that's better than 1 per 2 clocks.

```<code>Skylake_encode_scalar:    ; input in RDI, output in EAX
   tzcnt    rax, rdi       ; low bit.  No false dependency on Skylake.  GCC will probably xor-zero RAX because there is on Broadwell and earlier.
   bsr      rdi, rdi       ; high bit index.  same,same reg avoids false dep
   shl      eax, 6
   or       eax, edx

   ret                     ; goes away with inlining.
</code>```

This has 5 cycle latency from input to output: bitscan instructions are 3 cycles on Intel vs. 1 on AMD.  SHL + OR each add 1 cycle.

For throughput, we only bottleneck on one bit-scan per cycle (execution port 1), so we can do one encode per 2 cycles with 4 uops of front-end bandwidth left over for load, store, and loop overhead (or something else), assuming we have multiple independent encodes to do.

(But for the multiple independent encode case, SIMD may still be better for both AMD and Intel, if a cheap emulation of vplzcntq exists and the data is coming from memory.)

Scalar decode can be something like this:

```<code>decode:    ;; input in EDI, output in RAX
    xor   eax, eax           ; RAX=0
    bts   rax, rdi           ; RAX |= 1ULL << (high_bit_idx & 63)

    shr   edi, 6             ; extract low_bit_idx
    bts   rax, rdi           ; RAX |= 1ULL << low_bit_idx

    ret
</code>```

This has 3 shifts (including the bts) which on Skylake can only run on port0 or port6.  So on Intel it only costs 4 uops for the front-end (so 1 per clock as part of doing something else).  But if doing only this, it bottlenecks on shift throughput at 1 decode per 1.5 clock cycles.

On a 4GHz CPU, that's 2.666 billion decodes per second, so yeah we're doing pretty well hitting your targets :)

Or Ryzen, bts reg,reg is 2 uops , with 0.5c throughput, but shr can run on any port.  So it doesn't steal throughput from bts, and the whole thing is 6 uops (vs. Ryzen's pipeline being 5-wide at the narrowest point).  So 1 encode per 1.2 clock cycles, just bottlenecked on front-end cost.

With BMI2 available, starting with a 1 in a register and using shlx rax, rbx, rdi can replace the xor-zeroing + first BTS with a single uop, assuming the 1 in a register can be reused in a loop.

(This optimization is totally dependent on your compiler to find; flag-less shifts are just more efficient ways to copy-and-shift that become available with -march=haswell or -march=znver1, or other targets that have BMI2.)

Either way you're just going to write retval = 1ULL << (packed & 63) for decoding the first bit.  But if you're wondering which compilers make nice code here, this is what you're looking for.

Body:
I have a 56-bit number with potentially two set bits, e.g., 00000000 00000000 00000000 00000000 00000000 00000000 00000011. In other words, two bits are distributed among 56 bits, so that we have bin(56,2)=1540 possible permutations.

I now look for a loss-free mapping of such an 56 bit number to an 11-bit number that can carry 2048 and therefore also 1540. Knowing the structure, this 11-bit number is enough to store the value of my low-density (of ones) 56 bit number.

I want to maximize performance (this function should run millions or even billions of times per second if possible). So far, I only came up with some loop:

int inputNumber = 24; // 11000
int bitMask = 1;
int bit1 = 0, bit2 = 0;
for(int n = 0; n < 54; ++n, bitMask *= 2)
{
    if((inputNumber & bitMask) != 0)
    {
        if(bit1 != 0)
            bit1 = n;
        else
        {
            bit2 = n;
            break;
        }
    }
}

and using these two bits, I can easily generate some 1540 max number.

But is there no faster version than using such a loop?

Body:
Most ISAs have hardware support for a bit-scan instruction that finds the position of a set bit.  Use that instead of a naive loop or bithack for any architecture where you care about this running fast.  https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious has some tricks that are better than nothing, but those are all still much worse than a single efficient asm instruction.

But ISO C++ doesn't portably expose clz/ctz operations; it's only available via intrinsics / builtins for various implementations.  (And the x86 intrinsincs have quirks for all-zero input, corresponding to the asm instruction behaviour).

For some ISAs, it's a count-leading-zeros giving you 31 - highbit_index.  For others, it's a CTZ count trailing zeros operation, giving you the index of the low bit.  x86 has both.  (And its high-bit finder actually directly finds the high-bit index, not a leading-zero count, unless you use BMI1 lzcnt instead of traditional bsr)  https://en.wikipedia.org/wiki/Find_first_set has a table of what different ISAs have.

GCC portably provides __builtin_clz and __builtin_ctz; on ISAs without hardware support, they compile to a call to a helper functions.  See What is the fastest/most efficient way to find the highest set bit (msb) in an integer in C? and Implementation of __builtin_clz

(For 64-bit integers, you want the long long versions: like __builtin_ctzll GCC manual.)

If we only have a CLZ, use high=63-CLZ(n) and low= 63-CLZ((-n) & n) to isolate the low bit.  Note that x86's bsr instruction actually produces 63-CLZ(), i.e. the bit-index instead of the leading-zero count.  So 63-__builtin_clzll(n) can compile to a single instruction on x86; IIRC gcc does notice this.  Or 2 instructions if GCC uses an extra xor-zeroing to avoid the inconvenient false dependency.

If we only have CTZ, do low = CTZ(n) and high = CTZ(n & (n - 1)) to clear the lowest set bit.  (Leaving the high bit, assuming the number has exactly 2 set bits).

If we have both, low = CTZ(n) and high = 63-CLZ(n).  I'm not sure what GCC does on non-x86 ISAs where they aren't both available natively.  The GCC builtins are always available even when targeting HW that doesn't have it.  But the internal implementation can't use the above tricks because it doesn't know there are always exactly 2 bits set.

(I wrote out the full formulas; an earlier version of this answer had CLZ and CTZ reversed in this part.  I find that happens to me easily, especially when I also have to keep track of x86's bsr and bsr (bitscan reverse and forward) and remember that those are leading and trailing, respectively.)

So if you just use both CTZ and CLZ, you might end up with slow emulation for one of them.  Or fast emulation on ARM with rbit to bit-reverse for clz, which is 100% fine.

AVX512CD has SIMD VPLZCNTQ for 64-bit integers, so you could encode 2, 4, or 8x 64-bit integers in parallel with that on recent Intel CPUs.  For SSSE3 or AVX2, you can build a SIMD lzcnt by using pshufb _mm_shuffle_epi8 byte-shuffle as a 4-bit LUT and combining with _mm_max_epu8. There was a recent Q&A about this but I can't find it.  (It might have been for 16-bit integers only; wider requires more work.)

With this, a Skylake-X or Cascade Lake CPU could maybe compress 8x 64-bit integers per 2 or 3 clock cycles once you factor in the throughput cost of packing the results.  SIMD is certainly useful for packing 12-bit or 11-bit results into a contiguous bitstream, e.g. with variable-shift instructions, if that's what you want to do with the results.  At ~3 or 4GHz clock speed, that could maybe get you over 10 billion per clock with a single thread.  But only if the inputs come from contiguous memory.  Depending what you want to do with the results, it might cost a few more cycles to do more than just pack them down to 16-bit integers.  e.g. to pack into a bitstream.  But SIMD should be good for that with variable-shift instructions that can line up the 11 or 12 bits from each register into the right position to OR together after shuffling.

There's a tradeoff between coding efficiency and encode performance.  Using 12 bits for two 6-bit indices (of bit positions) is very simple both to compress and decompress, at least on hardware that has bit-scan instructions.

Or instead of bit-indices, one or both could be leading zero counts, so decoding would be (1ULL << 63) >> a.  1ULL>>63 is a fixed constant that you can actually right-shift, or the compiler could turn it into a left-shift of 1ULL << (63-a) which IIRC optimizes to 1 << (-a) in assembly for ISAs like x86 where shift instructions mask the shift count (look only at the low 6 bits).

Also, 2x 12 bits is a whole number of bytes, but 11 bits only gives you a whole number of bytes every 8 outputs, if you're packing them.  So indexing a bit-packed array is simpler.

0 is still a special case: maybe handle that by using all-ones bit-indices (i.e. index = bit 63, which is outside the low 56 bits).  On decode/decompress, you set the 2 bit positions (1ULL<<a) | (1ULL<<b) and then & mask to clear high bits.  Or bias your bit indices and have decode right shift by 1.

If we didn't have to handle zero then a modern x86 CPU could do 1 or 2 billion encodes per second if it didn't have to do anything else.  e.g. Skylake has 1 per clock throughput for bit-scan instructions and should be able to encode at 1 number per 2 clocks just bottlenecked on that.  (Or maybe better with SIMD).  With just 4 scalar instructions, we can get the low and high indices (64-bit tzcnt + bsr), shift by 6 bits, and OR together.1  Or on AMD, avoid bsr / bsf and manually do 63-lzcnt.

A branchy or branchless check for input == 0 to to set the final result to whatever hard-coded constant (like 63 , 63) should be cheap, though.

Compression on other ISAs like AArch64 is also cheap.  It has clz but not ctz.  Probably your best bet there is use an intrinsic for rbit to bit-reverse a number (so clz on the bit-reversed number directly gives you the bit-index of the low bit.  Which is now the high bit of the reversed version.)  Assuming rbit is as fast as add / sub, this is cheaper than using multiple instructions to clear the low bit.

If you really want 11 bits then you need to avoid the redundancy of 2x 6-bit being able to have either index larger than the other.  Like maybe have 6-bit a and 5-bit b, and have a<=b mean something special like b+=32.  I haven't thought this through fully.  You need to be able to encode 2 adjacent bits either near the top or bottom of the registers, or the 2 set bits could be as far apart as 28 bits, if we consider wrapping at the boundaries like a 56-bit rotate.

Melpomene's suggestion to isolate the low and high set bits might be useful as part of something else, but is only useful for encoding on targets where you only have one direction of bit-scan available, not both.  Even so, you wouldn't actually use both expressions.  Leading-zero count doesn't require you to isolate the low bit, you just need to clear it to get at the high bit.

Footnote 1:  decoding on x86 is also cheap:  x |= (1<<a) is 1 instruction: bts.  But many compilers have missed optimizations and don't notice this, instead actually shifting a 1.  bts reg, reg is 1 uop / 1 cycle latency on Intel since PPro, or sometimes 2 uops on AMD.  (Only the memory destination version is slow.)  https://agner.org/optimize/

Best encoding performance on AMD CPUs requires BMI1 tzcnt / lzcnt because bsr and bsf are slower (6 uops instead of 1 https://agner.org/optimize/).  On Ryzen, lzcnt is 1 uop, 1c latency, 4 per clock throughput.  But tzcnt is 2 uops.

With BMI1, the compiler could use blsr to clear the lowest set bit of a register (and copy it).  i.e. modern x86 has an instruction for dst = (SRC-1) bitwiseAND ( SRC ); that are single-uop on Intel but 2 uops on AMD.

But with lzcnt being more efficient than tzcnt on AMD Ryzen, probably the best asm for AMD doesn't use it.

Or maybe something like this (assuming exactly 2 bits, which apparently we can do).

(This asm is what you'd like to get your compiler to emit.  Don't actually use inline asm!)

Ryzen_encode_scalar:    ; input in RDI, output in EAX
   lzcnt    rcx, rdi       ; 63-high bit index
   tzcnt    rdx, rdi       ; low bit

   mov      eax, 63
   sub      eax, ecx

   shl      edx, 6
   or       eax, edx       ; (low_bit << 6) | high_bit

   ret                     ; goes away with inlining.

Shifting the low bit-index balances the lengths of the critical path, allowing better instruction-level parallelism, if we need 63-CLZ for the high bit.

Throughput: 7 uops total, and no execution-unit bottlenecks.  So at 5 uops per clock pipeline width, that's better than 1 per 2 clocks.

Skylake_encode_scalar:    ; input in RDI, output in EAX
   tzcnt    rax, rdi       ; low bit.  No false dependency on Skylake.  GCC will probably xor-zero RAX because there is on Broadwell and earlier.
   bsr      rdi, rdi       ; high bit index.  same,same reg avoids false dep
   shl      eax, 6
   or       eax, edx

   ret                     ; goes away with inlining.

This has 5 cycle latency from input to output: bitscan instructions are 3 cycles on Intel vs. 1 on AMD.  SHL + OR each add 1 cycle.

For throughput, we only bottleneck on one bit-scan per cycle (execution port 1), so we can do one encode per 2 cycles with 4 uops of front-end bandwidth left over for load, store, and loop overhead (or something else), assuming we have multiple independent encodes to do.

(But for the multiple independent encode case, SIMD may still be better for both AMD and Intel, if a cheap emulation of vplzcntq exists and the data is coming from memory.)

Scalar decode can be something like this:

decode:    ;; input in EDI, output in RAX
    xor   eax, eax           ; RAX=0
    bts   rax, rdi           ; RAX |= 1ULL << (high_bit_idx & 63)

    shr   edi, 6             ; extract low_bit_idx
    bts   rax, rdi           ; RAX |= 1ULL << low_bit_idx

    ret

This has 3 shifts (including the bts) which on Skylake can only run on port0 or port6.  So on Intel it only costs 4 uops for the front-end (so 1 per clock as part of doing something else).  But if doing only this, it bottlenecks on shift throughput at 1 decode per 1.5 clock cycles.

On a 4GHz CPU, that's 2.666 billion decodes per second, so yeah we're doing pretty well hitting your targets :)

Or Ryzen, bts reg,reg is 2 uops , with 0.5c throughput, but shr can run on any port.  So it doesn't steal throughput from bts, and the whole thing is 6 uops (vs. Ryzen's pipeline being 5-wide at the narrowest point).  So 1 encode per 1.2 clock cycles, just bottlenecked on front-end cost.

With BMI2 available, starting with a 1 in a register and using shlx rax, rbx, rdi can replace the xor-zeroing + first BTS with a single uop, assuming the 1 in a register can be reused in a loop.

(This optimization is totally dependent on your compiler to find; flag-less shifts are just more efficient ways to copy-and-shift that become available with -march=haswell or -march=znver1, or other targets that have BMI2.)

Either way you're just going to write retval = 1ULL << (packed & 63) for decoding the first bit.  But if you're wondering which compilers make nice code here, this is what you're looking for.


来源: stackexchange

问:
Xampp control panel is not showing
My Xampp control panel is not showing in the desktop (Windows 10), but can only up the servers through the shortcut (minimized option in the task bar).

As follows:

I have close the application without stopping the servers, will that be the case of this matter?

答: Uncheck "Start Control Panel Minimized" in the configuration

ContentLicense: CC BY-SA 3.0

Title: Xampp control panel is not showing

ContentLicense: CC BY-SA 4.0


问:
Android Google maps SDK draw a polyline with a dashed line
I tried to find a way to draw a dashed line for the polyline I need in my application, but the only style parameters that PolyLineOptions allows you to change are: color and width.
I kept on searching on google and kept hearing of "Symbols" But as far as I understood this is only for Javascript. Is there a possibility to somehow draw the line for my polyline as a dashed line or dotted one?
Also I've seen that on the iOS it is possible, should then android also have a similar function?</p>

答:
```<code>// Set a Stroke pattern [Add dots dashes and spaces as per your requirement]
List<PatternItem> pattern = Arrays.<PatternItem>asList(new Dot(), new Gap(20), new Dash(30), new Gap(20));

// Intialize PolylineOptions
PolylineOptions lineOptions = new PolylineOptions();

// set the pattern to polylineOptions like you set color,width etc.
lineOptions.setPattern(pattern);

// Add the polyline to map passing PolylineOptions
map.addPolyline(lineOptions);
</code>```


问:
Javascript recursion problem
I am trying to write a function that will change between an array of images. What I have makes sense to me, but when I run it as it is below then the first image loads, then the second image loads at some point (the transparency doesn't change) and then nothing happens. Here is the javascript code:

```<code>        var image1 = new Image();var image2 = new Image(); var image3 = new Image();
        image1.src = "images/website6.jpg"; image2.src = "images/website7.jpg"; image3.src = "images/sunset.jpg";
        var images = new Array("images/website6.jpg","images/website7.jpg","images/sunset.jpg");
        /*document.slide.style.opacity = 1;
        document.slide.stylebg.opacity = 0;*/
        setTimeout(function() { fade(images,0); }, 2000);
        function delay(arr,num)
        {
            document.slide.src = arr[num % 3];
            document.slide.style.opacity = 1;
            document.slidebg.style.opacity = 0;
            document.slidebg.src = arr[(num+1)%3];
            var number = num + 1;
            setTimeout(function() { fade(arr,number); }, 2000);
        }
        function fade(arr,num)
        {
            /*alert('fadebefore ' + (document.slide.style.opacity).toString())*/
            document.slide.style.opacity -= 0.1
            /*alert('fade')*/
            document.slide.stylebg.opacity += 0.1
            if (document.slide.style.opacity == 0)
            {
                setTimeout(function() { delay(arr,num); }, 150);
            }
            else
            {
                setTimeout(function() { fade(arr,num); }, 1500);
            }
        }
</code>```

The HTML is simple. I have two classes; style and stylebg. style sits in front of stylebg and then I change opacities and images as needed. The javascript seems logical to me, but it doesn't work as expected. Also worth noting is there are 3 comments. The first comment (line 3-4) is attemping to set the opacities to what they should be at the beginning. However, if I do this then I get even less progress than above: the first image loads and nothing else happens. The second two comments are used for debugging purposes. If I uncomment these then the image change occurs between the two alerts, which would seem to say the image change is caused by the opacity change.

So can anybody explain why it isn't doing what I expect it to? Thanks.

EDIT: Some more code:

HTML (This is the only part being affected):

```<code><div style="position: relative;">
<img src="images/sunset.jpg" id="slide" />
<img src="images/website6.jpg" id="slidebg" />
</div>
</code>```

CSS:

```#slide{
    display:block;
    margin-left:5;
    margin-right:auto;
    border: 1px solid black;
    z-index: 1;
    top: 0px;
    position: relative;
}
#slidebg{
    display:block;
    margin-left:auto;
    margin-right:auto;
    border: 1px solid black;
    z-index: 0;
    top: 0px;
    position: absolute;
}```

答:
You can't just refer to page elements by "id" value like that; you have to use "document.getElementById()":

```<code> var slideElement = document.getElementById('slide'), slidebgElement = document.getElementById('slidebg');
</code>```

Then you'd work with "slideElement.style" etc. instead of "document.slide.style".

Title: Javascript recursion problem

Body:
I am trying to write a function that will change between an array of images. What I have makes sense to me, but when I run it as it is below then the first image loads, then the second image loads at some point (the transparency doesn't change) and then nothing happens. Here is the javascript code:

        var image1 = new Image();var image2 = new Image(); var image3 = new Image();
        image1.src = "images/website6.jpg"; image2.src = "images/website7.jpg"; image3.src = "images/sunset.jpg";
        var images = new Array("images/website6.jpg","images/website7.jpg","images/sunset.jpg");
        /*document.slide.style.opacity = 1;
        document.slide.stylebg.opacity = 0;*/
        setTimeout(function() { fade(images,0); }, 2000);
        function delay(arr,num)
        {
            document.slide.src = arr[num % 3];
            document.slide.style.opacity = 1;
            document.slidebg.style.opacity = 0;
            document.slidebg.src = arr[(num+1)%3];
            var number = num + 1;
            setTimeout(function() { fade(arr,number); }, 2000);
        }
        function fade(arr,num)
        {
            /*alert('fadebefore ' + (document.slide.style.opacity).toString())*/
            document.slide.style.opacity -= 0.1
            /*alert('fade')*/
            document.slide.stylebg.opacity += 0.1
            if (document.slide.style.opacity == 0)
            {
                setTimeout(function() { delay(arr,num); }, 150);
            }
            else
            {
                setTimeout(function() { fade(arr,num); }, 1500);
            }
        }

The HTML is simple. I have two classes; style and stylebg. style sits in front of stylebg and then I change opacities and images as needed. The javascript seems logical to me, but it doesn't work as expected. Also worth noting is there are 3 comments. The first comment (line 3-4) is attemping to set the opacities to what they should be at the beginning. However, if I do this then I get even less progress than above: the first image loads and nothing else happens. The second two comments are used for debugging purposes. If I uncomment these then the image change occurs between the two alerts, which would seem to say the image change is caused by the opacity change.

So can anybody explain why it isn't doing what I expect it to? Thanks.

EDIT: Some more code:

HTML (This is the only part being affected):

CSS:

#slide{
    display:block;
    margin-left:5;
    margin-right:auto;
    border: 1px solid black;
    z-index: 1;
    top: 0px;
    position: relative;
}
#slidebg{
    display:block;
    margin-left:auto;
    margin-right:auto;
    border: 1px solid black;
    z-index: 0;
    top: 0px;
    position: absolute;
}

Body:
You can't just refer to page elements by "id" value like that; you have to use "document.getElementById()":

 var slideElement = document.getElementById('slide'), slidebgElement = document.getElementById('slidebg');

Then you'd work with "slideElement.style" etc. instead of "document.slide.style".


问:
Running Live streaming of local user using ffmpeg at Web plateform
I am using below command to stream my live desktop screen.

```<code>ffmpeg -f x11grab -r 1 -loglevel panic -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -i $DISPLAY -qscale 0 -f mpegts udp://192.168.3.151:1111
</code>```

udp://192.168.3.151:1111 - this is my streaming URL

I can see live streaming in the parole media player (in Linux platform), but I can't see this in a cross-network (i.e from windows PC - in the same network)

Is there any web platform so I can see my streaming from anywhere (either windows or linux) just using unique streaming URL or do I need to change my streaming command or method?

Any help is much appreciated

答:
I assuming that 192.168.3.151 is your linux machine IP and with mentioned URL (udp://192.168.200.151:1111) you are streaming on port 1111 in your local machine, so it is expected to see this stream only on it.

First of all you can use multicast UDP range (See more information here) to stream your desktop screen to local LAN like this:

```<code>ffmpeg -f x11grab -r 1 -loglevel panic -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -i $DISPLAY -qscale 0 -f mpegts udp://239.0.0.1:1111
</code>```

So, you can see the stream on other machines in local LAN.

If you want to stream your desktop screen on web, you have to use proper codec like h264 (MP4) and  use a media server like Nginx, Wowza or some like those and stream on it by using this command:

```<code>ffmpeg -f x11grab -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -framerate 25 -i $DISPLAY -c:v h264 -preset ultrafast -tune zerolatency -qscale 0 -f mpegts rtmp://<Media_Server_Address>:1935/live/<stream_name>
</code>```

Media_Server_Address is your server domain or IP address. This can be your web server or other server that a media server is installed on it.

live is an application that handle live streams. It can have another name but by default it's default name is live.

stream_name is An arbitrary name for stream.

In this scenario, you send the stream over RTMP on media server and then others can see it by for example HLS protocol via a player application like VLC player or via HTML5 video tag in an web page with this URL:

```<code>http://<Media_Server_Address>:1935/live/<stream_name>/playlist.m3u8
</code>```

Update:

This is an example of using Nginx as the media server:

Nginx config:

```<code>worker_processes  1;

events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1935;

        chunk_size 4000;

    application live {
            live on;
            allow publish all;
            allow play all;
        }

    }
}
</code>```

The FFmpeg command must execute on local PC to stream local PC's desktop to media server:

```<code>ffmpeg -f x11grab -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -framerate 25 -i $DISPLAY -c:v h264 -preset ultrafast -qscale 0 -f flv rtmp://<Media_Server_Address>:1935/live/localdesktop
</code>```

Now, users can play stream on other PC's using VLC with this URL:

```<code>rtmp://<Media_Server_Address>/live/localdesktop
</code>```

If HLS playback is required, just the hls config must be added to the Nginx config file. then users can use play hls stream just using this URL using VLC:

```<code>http://<Media_Server_Address>:1935/live/localdesktop/playlist.m3u8
</code>```

It is important to note that in this case, the same ffmpeg command must be used.

Body:
I am using below command to stream my live desktop screen.

ffmpeg -f x11grab -r 1 -loglevel panic -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -i $DISPLAY -qscale 0 -f mpegts udp://192.168.3.151:1111

udp://192.168.3.151:1111 - this is my streaming URL

I can see live streaming in the parole media player (in Linux platform), but I can't see this in a cross-network (i.e from windows PC - in the same network)

Is there any web platform so I can see my streaming from anywhere (either windows or linux) just using unique streaming URL or do I need to change my streaming command or method?

Any help is much appreciated

Body:
I assuming that 192.168.3.151 is your linux machine IP and with mentioned URL (udp://192.168.200.151:1111) you are streaming on port 1111 in your local machine, so it is expected to see this stream only on it.

First of all you can use multicast UDP range (See more information here) to stream your desktop screen to local LAN like this:

ffmpeg -f x11grab -r 1 -loglevel panic -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -i $DISPLAY -qscale 0 -f mpegts udp://239.0.0.1:1111

So, you can see the stream on other machines in local LAN.

If you want to stream your desktop screen on web, you have to use proper codec like h264 (MP4) and  use a media server like Nginx, Wowza or some like those and stream on it by using this command:

ffmpeg -f x11grab -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -framerate 25 -i $DISPLAY -c:v h264 -preset ultrafast -tune zerolatency -qscale 0 -f mpegts rtmp://<Media_Server_Address>:1935/live/<stream_name>

Media_Server_Address is your server domain or IP address. This can be your web server or other server that a media server is installed on it.

live is an application that handle live streams. It can have another name but by default it's default name is live.

stream_name is An arbitrary name for stream.

In this scenario, you send the stream over RTMP on media server and then others can see it by for example HLS protocol via a player application like VLC player or via HTML5 video tag in an web page with this URL:

http://<Media_Server_Address>:1935/live/<stream_name>/playlist.m3u8

Update:

This is an example of using Nginx as the media server:

Nginx config:

worker_processes  1;

events {
    worker_connections  1024;
}

rtmp {
    server {
        listen 1935;

        chunk_size 4000;

    application live {
            live on;
            allow publish all;
            allow play all;
        }

    }
}

The FFmpeg command must execute on local PC to stream local PC's desktop to media server:

ffmpeg -f x11grab -s `xdpyinfo | grep 'dimensions:'|awk '{print $2}'` -framerate 25 -i $DISPLAY -c:v h264 -preset ultrafast -qscale 0 -f flv rtmp://<Media_Server_Address>:1935/live/localdesktop

Now, users can play stream on other PC's using VLC with this URL:

rtmp://<Media_Server_Address>/live/localdesktop

If HLS playback is required, just the hls config must be added to the Nginx config file. then users can use play hls stream just using this URL using VLC:

http://<Media_Server_Address>:1935/live/localdesktop/playlist.m3u8

It is important to note that in this case, the same ffmpeg command must be used.


问:
How do I mix promises and pipe in gulp?
In my project I compile multiple bundles from source files in nested directories using rollup.

I had a gulpfile with the following code, which worked fine:

```<code>function build_app_js(file, name) {
  return gulp.src(file)
    .pipe(sourcemaps.init())
    .pipe(rollup({format:'iife'}))
    .pipe(terser())
    .pipe(rename(name + '.js'))
    .pipe(rename({suffix: '.min'}))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(js_apps_dir))
}
// call the above for multiple sets of file+app_name
</code>```

But then I changed one of the dependencies in my ES6 code which I accessed by relative path into an npm package, so it is now in node_modules. Rollup needs a plugin to resolve this, so I changed the above to this:

```<code>   .pipe(rollup({plugins: [resolveNodeModules()], format:'iife'}))
</code>```

However this simply does not work.

I consulted rollup's docs on gulp, and adapted the example to my case, so it now looks like this:

```<code>function build_app_js(file, name) {
  return rollup.rollup({
    input: file,
    plugins: [
      resolveNodeModules()
    ]
  }).then(bundle => {
    return bundle.write({
      file: js_apps_dir + '/' + name + '.js',
      format: 'iife',
      sourcemap: true
    });
  });
}
</code>```

This works, but has no minification step, and I don't know how to add one.

More generally, this is a totally different paradigm from using pipe(), and I do not know how to make both work together.

Do I try to add minification in the Promise syntax, or do I wrap the Promise function in such a way that I can use it with pipe?

答:
Answering own question after 8 days.

Minification can be achieved via rollup plugins, such as rollup-plugin-terser.

You just need to be careful with how you import them:

```<code>var rollup = require('rollup');
var resolveNodeModules = require('rollup-plugin-node-resolve');
//var terser = require('rollup-plugin-terser'); // WRONG
var {terser} = require('rollup-plugin-terser'); // CORRECT

function build_app_js(file, name) {
  return rollup.rollup({
    input: file,
    plugins: [
      resolveNodeModules(),
      terser()
    ]
  }).then(bundle => {
    return bundle.write({
      file: js_apps_dir + '/' + name + '.js',
      format: 'iife',
      sourcemap: true
    });
  });
}
</code>```

If you import it the wrong way, you will get a terser() is not a function type error, which is because it will have imported terser as a module.

It's a bit annoying that different rollup-plugins can't be imported the same way, but hey.

Title: How do I mix promises and pipe in gulp?

Body:
In my project I compile multiple bundles from source files in nested directories using rollup.

I had a gulpfile with the following code, which worked fine:

function build_app_js(file, name) {
  return gulp.src(file)
    .pipe(sourcemaps.init())
    .pipe(rollup({format:'iife'}))
    .pipe(terser())
    .pipe(rename(name + '.js'))
    .pipe(rename({suffix: '.min'}))
    .pipe(sourcemaps.write())
    .pipe(gulp.dest(js_apps_dir))
}
// call the above for multiple sets of file+app_name

But then I changed one of the dependencies in my ES6 code which I accessed by relative path into an npm package, so it is now in node_modules. Rollup needs a plugin to resolve this, so I changed the above to this:

   .pipe(rollup({plugins: [resolveNodeModules()], format:'iife'}))

However this simply does not work.

I consulted rollup's docs on gulp, and adapted the example to my case, so it now looks like this:

function build_app_js(file, name) {
  return rollup.rollup({
    input: file,
    plugins: [
      resolveNodeModules()
    ]
  }).then(bundle => {
    return bundle.write({
      file: js_apps_dir + '/' + name + '.js',
      format: 'iife',
      sourcemap: true
    });
  });
}

This works, but has no minification step, and I don't know how to add one.

More generally, this is a totally different paradigm from using pipe(), and I do not know how to make both work together.

Do I try to add minification in the Promise syntax, or do I wrap the Promise function in such a way that I can use it with pipe?

Body:
Answering own question after 8 days.

Minification can be achieved via rollup plugins, such as rollup-plugin-terser.

You just need to be careful with how you import them:

var rollup = require('rollup');
var resolveNodeModules = require('rollup-plugin-node-resolve');
//var terser = require('rollup-plugin-terser'); // WRONG
var {terser} = require('rollup-plugin-terser'); // CORRECT

function build_app_js(file, name) {
  return rollup.rollup({
    input: file,
    plugins: [
      resolveNodeModules(),
      terser()
    ]
  }).then(bundle => {
    return bundle.write({
      file: js_apps_dir + '/' + name + '.js',
      format: 'iife',
      sourcemap: true
    });
  });
}

If you import it the wrong way, you will get a terser() is not a function type error, which is because it will have imported terser as a module.

It's a bit annoying that different rollup-plugins can't be imported the same way, but hey.


问:
Excess space next to header
I'm having issues with excess space to the left of my header.

I had the same problem with my footer as well using  and
, but edited this to only using  elements instead, and this seemed to do the trick. I would, however, like to keep the  in the header, and preferably without using negative margin-left.

https://jsfiddle.net/thereseel/d75jurzy/6/

```<code><header>
 <nav>
  <ul class="mainnav">
   <li><a href="#">Home</a></li>
   <li><a href="#">Menu</a></li>
   <li><a href="#">Logo</a></li>
   <li><a href="#">Contact</a></li>
   <li><a href="#">Location</a></li>
  </ul>
 </nav>
</header>
</code>```

答:
you are facing excess space to the left of your header because of ul

browsers have default CSS values for many elements and ul is one of them.

from your current code just remove the padding

example:

```<code>.mainnav {
  /* add this to override default padding left of ul*/
  padding-left: 0;
}
</code>```

Here is Reference of default CSS values used by browser : w3schools link

Title: Excess space next to header

Body:
I'm having issues with excess space to the left of my header.

I had the same problem with my footer as well using  and
, but edited this to only using  elements instead, and this seemed to do the trick. I would, however, like to keep the  in the header, and preferably without using negative margin-left.

https://jsfiddle.net/thereseel/d75jurzy/6/

Home

Menu

Logo

Contact

Location

Body:
you are facing excess space to the left of your header because of ul

browsers have default CSS values for many elements and ul is one of them.

from your current code just remove the padding

example:

.mainnav {
  /* add this to override default padding left of ul*/
  padding-left: 0;
}

Here is Reference of default CSS values used by browser : w3schools link


问:
The output window in vs code is not editable, so how we can type the input when the program asks for it?
The Error is shown when I input anything in the output window</p>

答:
you cant input anything in output window.
if you want make any change or edit in output section you should first do debug in console box and then you can make any change you want</p>


问:
How to specialize constructor of template class in another class?
Consider the following classes:

```<code>// Class1.hpp
class Class1 {};

// Class2.hpp
class Class2 {};

// ClassA.hpp
#include "Class1.hpp"
#include "Class2.hpp"

class A {
private:
    enum class Enum {
        Enum1,
        Enum2
    };

    struct B {
        B(Enum argEum) : enumMember{argEnum} {}
        Enum enumMember;
    };

    template <class T>
    struct C : public B {}
};
</code>```

Now I would like to make the following specializations of the constructor of C:

```<code>C<Class1>::C() : B{Enum::Enum1} {}
C<Class2>::C() : B{Enum::Enum2} {}
</code>```

From what I tried I guess I have to place the specializations outside of the class definition of class A, but I don't really know how to do it.

答:
You can put a specialization anywhere a declaration of the templated entity may appear. Namespace scope is fine, but it requires you to fully qualify the thing your are specializing.

Furthermore, you may not specialize a member that wasn't declared in the primary template first. So with those two points in mind:

```<code>// In the class
template <class T>
struct C : public B {
    C() = delete;
};

// In namespace scope

template<>
A::C<Class1>::C() : B{Enum::Enum1} {}

template<>
A::C<Class2>::C() : B{Enum::Enum2} {}
</code>```

And a live example to refer to.

Body:
Consider the following classes:

// Class1.hpp
class Class1 {};

// Class2.hpp
class Class2 {};

// ClassA.hpp
#include "Class1.hpp"
#include "Class2.hpp"

class A {
private:
    enum class Enum {
        Enum1,
        Enum2
    };

    struct B {
        B(Enum argEum) : enumMember{argEnum} {}
        Enum enumMember;
    };

    template <class T>
    struct C : public B {}
};

Now I would like to make the following specializations of the constructor of C:

C<Class1>::C() : B{Enum::Enum1} {}
C<Class2>::C() : B{Enum::Enum2} {}

From what I tried I guess I have to place the specializations outside of the class definition of class A, but I don't really know how to do it.

Body:
You can put a specialization anywhere a declaration of the templated entity may appear. Namespace scope is fine, but it requires you to fully qualify the thing your are specializing.

Furthermore, you may not specialize a member that wasn't declared in the primary template first. So with those two points in mind:

// In the class
template <class T>
struct C : public B {
    C() = delete;
};

// In namespace scope

template<>
A::C<Class1>::C() : B{Enum::Enum1} {}

template<>
A::C<Class2>::C() : B{Enum::Enum2} {}

And a live example to refer to.


问:
gulp integration in Visual Studio 2017 not working
I'm attempting to get gulp integration into Visual Studio 2017. It's working on the command line. The Task Runner Explorer in VS2017 is telling me Failed to load. See output window.

The Output Window is telling me the following:

```<code>Failed to run "<ProjectPath>\Gulpfile.js"...
cmd.exe /c gulp --tasks-simple
<ProjectPath>\node_modules\node-sass\lib\binding.js:15
      throw new Error(errors.missingBinary());
      ^
Error: Missing binding <ProjectPath>\node_modules\node-sass\vendor\win32-x64-47\binding.node
Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 5.x
Found bindings for the following environments:
  - Windows 64-bit with Node.js 8.x
This usually happens because your environment has changed since running `npm install`.
Run `npm rebuild node-sass --force` to build the binding for your current environment.
</code>```

I attempt to run  npm rebuild node-sass --force, only to be told Error: Can't find Python executable "C:\Python36\python.EXE", you can set the PYTHON env variable., which I confirmed existed.

I'm not sure how much farther I want to go down this rabbit hole.  It appears to be a VS issue since everything works as expected on the command line. I'd like to get the gulp integration with VS working correctly.

答: I ran into this problem on both Visual Studio 2017 and 2019.  Apparently my Node install wasn't registered in the PATH variable (and I don't have permission to modify this on my work machine), so I manually added the link to Node at C:\Program Files\nodejs, moved that to the top location and that worked for me.

Body:
I'm attempting to get gulp integration into Visual Studio 2017. It's working on the command line. The Task Runner Explorer in VS2017 is telling me Failed to load. See output window.

The Output Window is telling me the following:

Failed to run "<ProjectPath>\Gulpfile.js"...
cmd.exe /c gulp --tasks-simple
<ProjectPath>\node_modules\node-sass\lib\binding.js:15
      throw new Error(errors.missingBinary());
      ^
Error: Missing binding <ProjectPath>\node_modules\node-sass\vendor\win32-x64-47\binding.node
Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 5.x
Found bindings for the following environments:
  - Windows 64-bit with Node.js 8.x
This usually happens because your environment has changed since running `npm install`.
Run `npm rebuild node-sass --force` to build the binding for your current environment.

I attempt to run  npm rebuild node-sass --force, only to be told Error: Can't find Python executable "C:\Python36\python.EXE", you can set the PYTHON env variable., which I confirmed existed.

I'm not sure how much farther I want to go down this rabbit hole.  It appears to be a VS issue since everything works as expected on the command line. I'd like to get the gulp integration with VS working correctly.


问:
What is an idiomatic Scala way to "remove" one element from an immutable List?
I have a List, which may contain elements that will compare as equal. I would like a similar List, but with one element removed. So from (A, B, C, B, D) I would like to be able to "remove" just one B to get e.g. (A, C, B, D). The order of the elements in the result does not matter.

I have working code, written in a Lisp-inspired way in Scala. Is there a more idiomatic way
to do this?

The context is a card game where two decks of standard cards are in play, so there may
be duplicate cards but still played one at a time.

```<code>def removeOne(c: Card, left: List[Card], right: List[Card]): List[Card] = {
  if (Nil == right) {
    return left
  }
  if (c == right.head) {
    return left ::: right.tail
  }
  return removeOne(c, right.head :: left, right.tail)
}

def removeCard(c: Card, cards: List[Card]): List[Card] = {
  return removeOne(c, Nil, cards)
}
</code>```

答:
I haven't seen this possibility in the answers above, so:

```<code>scala> def remove(num: Int, list: List[Int]) = list diff List(num)
remove: (num: Int,list: List[Int])List[Int]

scala> remove(2,List(1,2,3,4,5))
res2: List[Int] = List(1, 3, 4, 5)
</code>```

Edit:

```<code>scala> remove(2,List(2,2,2))
res0: List[Int] = List(2, 2)
</code>```

Like a charm :-).

Body:
I have a List, which may contain elements that will compare as equal. I would like a similar List, but with one element removed. So from (A, B, C, B, D) I would like to be able to "remove" just one B to get e.g. (A, C, B, D). The order of the elements in the result does not matter.

I have working code, written in a Lisp-inspired way in Scala. Is there a more idiomatic way
to do this?

The context is a card game where two decks of standard cards are in play, so there may
be duplicate cards but still played one at a time.

def removeOne(c: Card, left: List[Card], right: List[Card]): List[Card] = {
  if (Nil == right) {
    return left
  }
  if (c == right.head) {
    return left ::: right.tail
  }
  return removeOne(c, right.head :: left, right.tail)
}

def removeCard(c: Card, cards: List[Card]): List[Card] = {
  return removeOne(c, Nil, cards)
}

Body:
I haven't seen this possibility in the answers above, so:

scala> def remove(num: Int, list: List[Int]) = list diff List(num)
remove: (num: Int,list: List[Int])List[Int]

scala> remove(2,List(1,2,3,4,5))
res2: List[Int] = List(1, 3, 4, 5)

Edit:

scala> remove(2,List(2,2,2))
res0: List[Int] = List(2, 2)

Like a charm :-).


问:
Scrollbar disappear and the panel becomes bigger
I am designing a window with GridBagLayout. This principal panel is a scroll panel. It is composed by several panels. All of them are GridBagLayout. In one of the panels, there are two scroll panels containing a text field.

The problem

When writing in one of these text fields the size of it stays unchanged and appears in the scroll bar. But, when I stop writing, the scroll bar disappears and the text field becomes bigger. That makes the adjacent cells bigger as well.

In the code, the scroll panes are scrollPane_1 and scrollPane_2:

```<code>public class PruebaQ extends JPanel {
    public class SignalingMessagePane extends JPanel {

        // Components
        private JCheckBox singMessChckBx1;
        private JLabel familyLabel1;
        private JComboBox<ComboItem> familyCmbBx1;
        private JTextArea textTField1;

        public SignalingMessagePane() {
            super();
        }

        public void initialize() {
            this.setBorder(new LineBorder(Color.LIGHT_GRAY));

            GridBagLayout gbl_nst5Panel1 = new GridBagLayout();
            gbl_nst5Panel1.columnWidths = new int[] { 0, 0, 0, 0, 0, 0 };
            gbl_nst5Panel1.rowHeights = new int[] { 0, 0, 0 };
            gbl_nst5Panel1.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
            gbl_nst5Panel1.rowWeights = new double[] { 0.0, 0.0, 0.0 };
            this.setLayout(gbl_nst5Panel1);

            singMessChckBx1 = new JCheckBox("");
            singMessChckBx1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    familyCmbBx1.setEnabled(singMessChckBx1.isSelected());
                    textTField1.setEnabled(singMessChckBx1.isSelected());
                }
            });
            GridBagConstraints gbc_singMessChckBx1 = new GridBagConstraints();
            gbc_singMessChckBx1.anchor = GridBagConstraints.NORTHWEST;
            gbc_singMessChckBx1.insets = new Insets(5, 5, 0, 0);
            gbc_singMessChckBx1.gridx = 0;
            gbc_singMessChckBx1.gridy = 0;
            this.add(singMessChckBx1, gbc_singMessChckBx1);

            familyLabel1 = new JLabel("Label");
            GridBagConstraints gbc_familyLabel1 = new GridBagConstraints();
            gbc_familyLabel1.insets = new Insets(0, 40, 0, 5);
            gbc_familyLabel1.anchor = GridBagConstraints.EAST;
            gbc_familyLabel1.gridx = 0;
            gbc_familyLabel1.gridy = 1;
            this.add(familyLabel1, gbc_familyLabel1);

            familyCmbBx1 = new JComboBox();
            GridBagConstraints gbc_familyCmbBx1 = new GridBagConstraints();
            gbc_familyCmbBx1.weightx = 0.6;
            gbc_familyCmbBx1.insets = new Insets(0, 0, 0, 5);
            gbc_familyCmbBx1.fill = GridBagConstraints.HORIZONTAL;
            gbc_familyCmbBx1.gridx = 1;
            gbc_familyCmbBx1.gridy = 1;
            this.add(familyCmbBx1, gbc_familyCmbBx1);
            familyCmbBx1.setEnabled(false);

            textTField1 = new JTextArea();
            GridBagConstraints gbc_textTField1 = new GridBagConstraints();
            gbc_textTField1.weighty = 1.0;
            gbc_textTField1.weightx = 1.0;
            gbc_textTField1.gridwidth = 3;
            gbc_textTField1.insets = new Insets(10, 5, 5, 0);
            gbc_textTField1.fill = GridBagConstraints.BOTH;
            gbc_textTField1.gridx = 0;
            gbc_textTField1.gridy = 2;
            this.add(textTField1, gbc_textTField1);
            textTField1.setEnabled(false);
        }
    }

    private JScrollPane scrollPane_2;
    private JTextArea txtrDetectionZone;
    private JScrollPane scrollPane_1;
    private JTextArea txtrRelevanceZone;
    private JPanel panel;
    private JPanel nestedPanel2;
    private JPanel nst2RefPositionPanel;
    private JScrollPane scrollPane;
    private JLabel latitudeLabel;
    private JTextField latitudeTxt;
    private JLabel longitudeLabel;
    private JTextField longitudeTxt;
    private JLabel zoomLabel;
    private JTextField zoomTxt;
    private JPanel nestedPanel3;
    private JLabel detectionZoneLabel;
    private JLabel relevanceZoneLabel;
    private JPanel nestedPanel5;
    private SignalingMessagePane[] nstPanel;

    /**
     * Create the panel.
     */
    public PruebaQ() {

        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{0};
        gridBagLayout.rowHeights = new int[]{0};
        gridBagLayout.columnWeights = new double[]{1.0};
        gridBagLayout.rowWeights = new double[]{1.0};
        setLayout(gridBagLayout);

        panel = new JPanel();
        scrollPane = new JScrollPane(panel);
        GridBagConstraints gbc_scrollPane = new GridBagConstraints();
        gbc_scrollPane.weighty = 1.0;
        gbc_scrollPane.weightx = 1.0;
        gbc_scrollPane.fill = GridBagConstraints.BOTH;
        gbc_scrollPane.gridx = 0;
        gbc_scrollPane.gridy = 0;
        add(scrollPane, gbc_scrollPane);
        GridBagLayout gbl_panel = new GridBagLayout();
        gbl_panel.columnWidths = new int[]{0, 0, 0};
        gbl_panel.rowHeights = new int[]{0, 0, 0};
        gbl_panel.columnWeights = new double[]{0.0, 0.0, 0.0};
        gbl_panel.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
        panel.setLayout(gbl_panel);

                nestedPanel2 = new JPanel();
                GridBagConstraints gbc_nestedPanel2 = new GridBagConstraints();
                gbc_nestedPanel2.weighty = 1.0;
                gbc_nestedPanel2.weightx = 1.0;
                gbc_nestedPanel2.fill = GridBagConstraints.BOTH;
                gbc_nestedPanel2.insets = new Insets(20, 10, 10, 10);
                gbc_nestedPanel2.gridx = 1;
                gbc_nestedPanel2.gridy = 1;
                panel.add(nestedPanel2, gbc_nestedPanel2);
                GridBagLayout gbl_nestedPanel2 = new GridBagLayout();
                gbl_nestedPanel2.columnWidths = new int[]{0};
                gbl_nestedPanel2.rowHeights = new int[]{0, 0};
                gbl_nestedPanel2.columnWeights = new double[]{1.0};
                gbl_nestedPanel2.rowWeights = new double[]{0.0, 1.0};
                nestedPanel2.setLayout(gbl_nestedPanel2);

                nst2RefPositionPanel = new JPanel();
                nst2RefPositionPanel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Position", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
                GridBagConstraints gbc_nst2RefPositionPanel = new GridBagConstraints();
                gbc_nst2RefPositionPanel.weighty = 1.0;
                gbc_nst2RefPositionPanel.weightx = 1.0;
                gbc_nst2RefPositionPanel.insets = new Insets(0, 30, 0, 30);
                gbc_nst2RefPositionPanel.fill = GridBagConstraints.BOTH;
                gbc_nst2RefPositionPanel.gridx = 0;
                gbc_nst2RefPositionPanel.gridy = 1;
                nestedPanel2.add(nst2RefPositionPanel, gbc_nst2RefPositionPanel);
                GridBagLayout gbl_nst2RefPositionPanel = new GridBagLayout();
                gbl_nst2RefPositionPanel.columnWidths = new int[]{0, 0};
                gbl_nst2RefPositionPanel.rowHeights = new int[]{0, 0, 0};
                gbl_nst2RefPositionPanel.columnWeights = new double[]{0.0, 0.0};
                gbl_nst2RefPositionPanel.rowWeights = new double[]{0.0, 0.0, 0.0};
                nst2RefPositionPanel.setLayout(gbl_nst2RefPositionPanel);

                latitudeLabel = new JLabel("label");
                GridBagConstraints gbc_latitudeLabel = new GridBagConstraints();
                gbc_latitudeLabel.insets = new Insets(10, 20, 0, 10);
                gbc_latitudeLabel.anchor = GridBagConstraints.WEST;
                gbc_latitudeLabel.gridx = 0;
                gbc_latitudeLabel.gridy = 0;
                nst2RefPositionPanel.add(latitudeLabel, gbc_latitudeLabel);

                latitudeTxt = new JTextField();
                GridBagConstraints gbc_latitudeTxt = new GridBagConstraints();
                gbc_latitudeTxt.insets = new Insets(10, 0, 0, 20);
                gbc_latitudeTxt.fill = GridBagConstraints.HORIZONTAL;
                gbc_latitudeTxt.gridx = 1;
                gbc_latitudeTxt.gridy = 0;
                nst2RefPositionPanel.add(latitudeTxt, gbc_latitudeTxt);
                latitudeTxt.setColumns(10);

                longitudeLabel = new JLabel("label");
                GridBagConstraints gbc_longitudeLabel = new GridBagConstraints();
                gbc_longitudeLabel.anchor = GridBagConstraints.WEST;
                gbc_longitudeLabel.insets = new Insets(0, 20, 0, 10);
                gbc_longitudeLabel.gridx = 0;
                gbc_longitudeLabel.gridy = 1;
                nst2RefPositionPanel.add(longitudeLabel, gbc_longitudeLabel);

                longitudeTxt = new JTextField();
                GridBagConstraints gbc_longitudeTxt = new GridBagConstraints();
                gbc_longitudeTxt.insets = new Insets(0, 0, 0, 20);
                gbc_longitudeTxt.fill = GridBagConstraints.HORIZONTAL;
                gbc_longitudeTxt.gridx = 1;
                gbc_longitudeTxt.gridy = 1;
                nst2RefPositionPanel.add(longitudeTxt, gbc_longitudeTxt);
                longitudeTxt.setColumns(10);

                zoomLabel = new JLabel("label");
                GridBagConstraints gbc_zoomLabel = new GridBagConstraints();
                gbc_zoomLabel.anchor = GridBagConstraints.WEST;
                gbc_zoomLabel.insets = new Insets(0, 20, 15, 10);
                gbc_zoomLabel.gridx = 0;
                gbc_zoomLabel.gridy = 2;
                nst2RefPositionPanel.add(zoomLabel, gbc_zoomLabel);

                zoomTxt = new JTextField();
                GridBagConstraints gbc_zoomTxt = new GridBagConstraints();
                gbc_zoomTxt.insets = new Insets(0, 0, 15, 20);
                gbc_zoomTxt.fill = GridBagConstraints.HORIZONTAL;
                gbc_zoomTxt.gridx = 1;
                gbc_zoomTxt.gridy = 2;
                nst2RefPositionPanel.add(zoomTxt, gbc_zoomTxt);
                zoomTxt.setColumns(10);

                nestedPanel3 = new JPanel();
                GridBagConstraints gbc_nestedPanel3 = new GridBagConstraints();
                gbc_nestedPanel3.weighty = 1.0;
                gbc_nestedPanel3.weightx = 1.0;
                gbc_nestedPanel3.fill = GridBagConstraints.BOTH;
                gbc_nestedPanel3.insets = new Insets(20, 10, 15, 20);
                gbc_nestedPanel3.gridx = 2;
                gbc_nestedPanel3.gridy = 1;
                panel.add(nestedPanel3, gbc_nestedPanel3);
                GridBagLayout gbl_nestedPanel3 = new GridBagLayout();
                gbl_nestedPanel3.columnWidths = new int[]{0};
                gbl_nestedPanel3.rowHeights = new int[]{0, 0, 0, 0};
                gbl_nestedPanel3.columnWeights = new double[]{0.0};
                gbl_nestedPanel3.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0};
                nestedPanel3.setLayout(gbl_nestedPanel3);

                detectionZoneLabel = new JLabel("label");
                GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
                gbc_lblNewLabel.anchor = GridBagConstraints.WEST;
                gbc_lblNewLabel.insets = new Insets(0, 0, 1, 0);
                gbc_lblNewLabel.gridx = 0;
                gbc_lblNewLabel.gridy = 0;
                nestedPanel3.add(detectionZoneLabel, gbc_lblNewLabel);

                scrollPane_2 = new JScrollPane();
                GridBagConstraints gbc_scrollPane_2 = new GridBagConstraints();
                gbc_scrollPane_2.weighty = 1.0;
                gbc_scrollPane_2.weightx = 1.0;
                gbc_scrollPane_2.fill = GridBagConstraints.BOTH;
                gbc_scrollPane_2.gridx = 0;
                gbc_scrollPane_2.gridy = 1;
                nestedPanel3.add(scrollPane_2, gbc_scrollPane_2);

                txtrDetectionZone = new JTextArea();
                scrollPane_2.setViewportView(txtrDetectionZone);

                relevanceZoneLabel = new JLabel("label");
                GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
                gbc_lblNewLabel_1.anchor = GridBagConstraints.WEST;
                gbc_lblNewLabel_1.insets = new Insets(5, 0, 1, 0);
                gbc_lblNewLabel_1.gridx = 0;
                gbc_lblNewLabel_1.gridy = 2;
                nestedPanel3.add(relevanceZoneLabel, gbc_lblNewLabel_1);

                scrollPane_1 = new JScrollPane();
                GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
                gbc_scrollPane_1.weighty = 1.0;
                gbc_scrollPane_1.weightx = 1.0;
                gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
                gbc_scrollPane_1.gridx = 0;
                gbc_scrollPane_1.gridy = 3;
                nestedPanel3.add(scrollPane_1, gbc_scrollPane_1);

                txtrRelevanceZone = new JTextArea();
                scrollPane_1.setViewportView(txtrRelevanceZone);

                nestedPanel5 = new JPanel();
                nestedPanel5.setBorder(new TitledBorder(null, "Messages", TitledBorder.LEADING, TitledBorder.TOP, null, null));
                GridBagConstraints gbc_nestedPanel5 = new GridBagConstraints();
                gbc_nestedPanel5.weighty = 1.0;
                gbc_nestedPanel5.weightx = 1.0;
                gbc_nestedPanel5.fill = GridBagConstraints.BOTH;
                gbc_nestedPanel5.gridwidth = 2;
                gbc_nestedPanel5.insets = new Insets(10, 10, 10, 10);
                gbc_nestedPanel5.gridx = 1;
                gbc_nestedPanel5.gridy = 2;
                panel.add(nestedPanel5, gbc_nestedPanel5);
                GridBagLayout gbl_nestedPanel5 = new GridBagLayout();
                gbl_nestedPanel5.columnWidths = new int[]{0, 0};
                gbl_nestedPanel5.rowHeights = new int[]{0, 0};
                gbl_nestedPanel5.columnWeights = new double[]{0.0, 0.0};
                gbl_nestedPanel5.rowWeights = new double[]{0.0, 0.0};
                nestedPanel5.setLayout(gbl_nestedPanel5);

                for(int index = 0 ; index < 4; index++) {
                    nstPanel[index] = new SignalingMessagePane();
                    nstPanel[index].initialize();
                    GridBagConstraints gbc_nst5Panel1 = new GridBagConstraints();
                    gbc_nst5Panel1.weighty = 0.5;
                    gbc_nst5Panel1.weightx = 0.5;
                    gbc_nst5Panel1.insets = new Insets(5, 5, 5, 10);
                    gbc_nst5Panel1.fill = GridBagConstraints.BOTH;
                    gbc_nst5Panel1.gridx = index % 2;
                    gbc_nst5Panel1.gridy = index > 1? 1:0;
                    nestedPanel5.add(nstPanel[index], gbc_nst5Panel1);
                }
    }

}
</code>```

How can I avoid this behaviour? What am I doing wrong?

答:
Change this line of the code you posted:

```<code>txtrDetectionZone = new JTextArea();
</code>```

Give the JTextArea an initial size by using the constructor that takes the number of rows and columns, e.g.

```<code>txtrDetectionZone = new JTextArea(10, 50);
</code>```

Also you can set the scrollbar policy so that the scrollbars always appear, e.g.

```<code>scrollPane_2 = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
</code>```

That way, the scrollbars will not appear and disappear.

Body:
I am designing a window with GridBagLayout. This principal panel is a scroll panel. It is composed by several panels. All of them are GridBagLayout. In one of the panels, there are two scroll panels containing a text field.

The problem

When writing in one of these text fields the size of it stays unchanged and appears in the scroll bar. But, when I stop writing, the scroll bar disappears and the text field becomes bigger. That makes the adjacent cells bigger as well.

In the code, the scroll panes are scrollPane_1 and scrollPane_2:

public class PruebaQ extends JPanel {
    public class SignalingMessagePane extends JPanel {

        // Components
        private JCheckBox singMessChckBx1;
        private JLabel familyLabel1;
        private JComboBox<ComboItem> familyCmbBx1;
        private JTextArea textTField1;

        public SignalingMessagePane() {
            super();
        }

        public void initialize() {
            this.setBorder(new LineBorder(Color.LIGHT_GRAY));

            GridBagLayout gbl_nst5Panel1 = new GridBagLayout();
            gbl_nst5Panel1.columnWidths = new int[] { 0, 0, 0, 0, 0, 0 };
            gbl_nst5Panel1.rowHeights = new int[] { 0, 0, 0 };
            gbl_nst5Panel1.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
            gbl_nst5Panel1.rowWeights = new double[] { 0.0, 0.0, 0.0 };
            this.setLayout(gbl_nst5Panel1);

            singMessChckBx1 = new JCheckBox("");
            singMessChckBx1.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    familyCmbBx1.setEnabled(singMessChckBx1.isSelected());
                    textTField1.setEnabled(singMessChckBx1.isSelected());
                }
            });
            GridBagConstraints gbc_singMessChckBx1 = new GridBagConstraints();
            gbc_singMessChckBx1.anchor = GridBagConstraints.NORTHWEST;
            gbc_singMessChckBx1.insets = new Insets(5, 5, 0, 0);
            gbc_singMessChckBx1.gridx = 0;
            gbc_singMessChckBx1.gridy = 0;
            this.add(singMessChckBx1, gbc_singMessChckBx1);

            familyLabel1 = new JLabel("Label");
            GridBagConstraints gbc_familyLabel1 = new GridBagConstraints();
            gbc_familyLabel1.insets = new Insets(0, 40, 0, 5);
            gbc_familyLabel1.anchor = GridBagConstraints.EAST;
            gbc_familyLabel1.gridx = 0;
            gbc_familyLabel1.gridy = 1;
            this.add(familyLabel1, gbc_familyLabel1);

            familyCmbBx1 = new JComboBox();
            GridBagConstraints gbc_familyCmbBx1 = new GridBagConstraints();
            gbc_familyCmbBx1.weightx = 0.6;
            gbc_familyCmbBx1.insets = new Insets(0, 0, 0, 5);
            gbc_familyCmbBx1.fill = GridBagConstraints.HORIZONTAL;
            gbc_familyCmbBx1.gridx = 1;
            gbc_familyCmbBx1.gridy = 1;
            this.add(familyCmbBx1, gbc_familyCmbBx1);
            familyCmbBx1.setEnabled(false);

            textTField1 = new JTextArea();
            GridBagConstraints gbc_textTField1 = new GridBagConstraints();
            gbc_textTField1.weighty = 1.0;
            gbc_textTField1.weightx = 1.0;
            gbc_textTField1.gridwidth = 3;
            gbc_textTField1.insets = new Insets(10, 5, 5, 0);
            gbc_textTField1.fill = GridBagConstraints.BOTH;
            gbc_textTField1.gridx = 0;
            gbc_textTField1.gridy = 2;
            this.add(textTField1, gbc_textTField1);
            textTField1.setEnabled(false);
        }
    }

    private JScrollPane scrollPane_2;
    private JTextArea txtrDetectionZone;
    private JScrollPane scrollPane_1;
    private JTextArea txtrRelevanceZone;
    private JPanel panel;
    private JPanel nestedPanel2;
    private JPanel nst2RefPositionPanel;
    private JScrollPane scrollPane;
    private JLabel latitudeLabel;
    private JTextField latitudeTxt;
    private JLabel longitudeLabel;
    private JTextField longitudeTxt;
    private JLabel zoomLabel;
    private JTextField zoomTxt;
    private JPanel nestedPanel3;
    private JLabel detectionZoneLabel;
    private JLabel relevanceZoneLabel;
    private JPanel nestedPanel5;
    private SignalingMessagePane[] nstPanel;

    /**
     * Create the panel.
     */
    public PruebaQ() {

        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[]{0};
        gridBagLayout.rowHeights = new int[]{0};
        gridBagLayout.columnWeights = new double[]{1.0};
        gridBagLayout.rowWeights = new double[]{1.0};
        setLayout(gridBagLayout);

        panel = new JPanel();
        scrollPane = new JScrollPane(panel);
        GridBagConstraints gbc_scrollPane = new GridBagConstraints();
        gbc_scrollPane.weighty = 1.0;
        gbc_scrollPane.weightx = 1.0;
        gbc_scrollPane.fill = GridBagConstraints.BOTH;
        gbc_scrollPane.gridx = 0;
        gbc_scrollPane.gridy = 0;
        add(scrollPane, gbc_scrollPane);
        GridBagLayout gbl_panel = new GridBagLayout();
        gbl_panel.columnWidths = new int[]{0, 0, 0};
        gbl_panel.rowHeights = new int[]{0, 0, 0};
        gbl_panel.columnWeights = new double[]{0.0, 0.0, 0.0};
        gbl_panel.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
        panel.setLayout(gbl_panel);

                nestedPanel2 = new JPanel();
                GridBagConstraints gbc_nestedPanel2 = new GridBagConstraints();
                gbc_nestedPanel2.weighty = 1.0;
                gbc_nestedPanel2.weightx = 1.0;
                gbc_nestedPanel2.fill = GridBagConstraints.BOTH;
                gbc_nestedPanel2.insets = new Insets(20, 10, 10, 10);
                gbc_nestedPanel2.gridx = 1;
                gbc_nestedPanel2.gridy = 1;
                panel.add(nestedPanel2, gbc_nestedPanel2);
                GridBagLayout gbl_nestedPanel2 = new GridBagLayout();
                gbl_nestedPanel2.columnWidths = new int[]{0};
                gbl_nestedPanel2.rowHeights = new int[]{0, 0};
                gbl_nestedPanel2.columnWeights = new double[]{1.0};
                gbl_nestedPanel2.rowWeights = new double[]{0.0, 1.0};
                nestedPanel2.setLayout(gbl_nestedPanel2);

                nst2RefPositionPanel = new JPanel();
                nst2RefPositionPanel.setBorder(new TitledBorder(UIManager.getBorder("TitledBorder.border"), "Position", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
                GridBagConstraints gbc_nst2RefPositionPanel = new GridBagConstraints();
                gbc_nst2RefPositionPanel.weighty = 1.0;
                gbc_nst2RefPositionPanel.weightx = 1.0;
                gbc_nst2RefPositionPanel.insets = new Insets(0, 30, 0, 30);
                gbc_nst2RefPositionPanel.fill = GridBagConstraints.BOTH;
                gbc_nst2RefPositionPanel.gridx = 0;
                gbc_nst2RefPositionPanel.gridy = 1;
                nestedPanel2.add(nst2RefPositionPanel, gbc_nst2RefPositionPanel);
                GridBagLayout gbl_nst2RefPositionPanel = new GridBagLayout();
                gbl_nst2RefPositionPanel.columnWidths = new int[]{0, 0};
                gbl_nst2RefPositionPanel.rowHeights = new int[]{0, 0, 0};
                gbl_nst2RefPositionPanel.columnWeights = new double[]{0.0, 0.0};
                gbl_nst2RefPositionPanel.rowWeights = new double[]{0.0, 0.0, 0.0};
                nst2RefPositionPanel.setLayout(gbl_nst2RefPositionPanel);

                latitudeLabel = new JLabel("label");
                GridBagConstraints gbc_latitudeLabel = new GridBagConstraints();
                gbc_latitudeLabel.insets = new Insets(10, 20, 0, 10);
                gbc_latitudeLabel.anchor = GridBagConstraints.WEST;
                gbc_latitudeLabel.gridx = 0;
                gbc_latitudeLabel.gridy = 0;
                nst2RefPositionPanel.add(latitudeLabel, gbc_latitudeLabel);

                latitudeTxt = new JTextField();
                GridBagConstraints gbc_latitudeTxt = new GridBagConstraints();
                gbc_latitudeTxt.insets = new Insets(10, 0, 0, 20);
                gbc_latitudeTxt.fill = GridBagConstraints.HORIZONTAL;
                gbc_latitudeTxt.gridx = 1;
                gbc_latitudeTxt.gridy = 0;
                nst2RefPositionPanel.add(latitudeTxt, gbc_latitudeTxt);
                latitudeTxt.setColumns(10);

                longitudeLabel = new JLabel("label");
                GridBagConstraints gbc_longitudeLabel = new GridBagConstraints();
                gbc_longitudeLabel.anchor = GridBagConstraints.WEST;
                gbc_longitudeLabel.insets = new Insets(0, 20, 0, 10);
                gbc_longitudeLabel.gridx = 0;
                gbc_longitudeLabel.gridy = 1;
                nst2RefPositionPanel.add(longitudeLabel, gbc_longitudeLabel);

                longitudeTxt = new JTextField();
                GridBagConstraints gbc_longitudeTxt = new GridBagConstraints();
                gbc_longitudeTxt.insets = new Insets(0, 0, 0, 20);
                gbc_longitudeTxt.fill = GridBagConstraints.HORIZONTAL;
                gbc_longitudeTxt.gridx = 1;
                gbc_longitudeTxt.gridy = 1;
                nst2RefPositionPanel.add(longitudeTxt, gbc_longitudeTxt);
                longitudeTxt.setColumns(10);

                zoomLabel = new JLabel("label");
                GridBagConstraints gbc_zoomLabel = new GridBagConstraints();
                gbc_zoomLabel.anchor = GridBagConstraints.WEST;
                gbc_zoomLabel.insets = new Insets(0, 20, 15, 10);
                gbc_zoomLabel.gridx = 0;
                gbc_zoomLabel.gridy = 2;
                nst2RefPositionPanel.add(zoomLabel, gbc_zoomLabel);

                zoomTxt = new JTextField();
                GridBagConstraints gbc_zoomTxt = new GridBagConstraints();
                gbc_zoomTxt.insets = new Insets(0, 0, 15, 20);
                gbc_zoomTxt.fill = GridBagConstraints.HORIZONTAL;
                gbc_zoomTxt.gridx = 1;
                gbc_zoomTxt.gridy = 2;
                nst2RefPositionPanel.add(zoomTxt, gbc_zoomTxt);
                zoomTxt.setColumns(10);

                nestedPanel3 = new JPanel();
                GridBagConstraints gbc_nestedPanel3 = new GridBagConstraints();
                gbc_nestedPanel3.weighty = 1.0;
                gbc_nestedPanel3.weightx = 1.0;
                gbc_nestedPanel3.fill = GridBagConstraints.BOTH;
                gbc_nestedPanel3.insets = new Insets(20, 10, 15, 20);
                gbc_nestedPanel3.gridx = 2;
                gbc_nestedPanel3.gridy = 1;
                panel.add(nestedPanel3, gbc_nestedPanel3);
                GridBagLayout gbl_nestedPanel3 = new GridBagLayout();
                gbl_nestedPanel3.columnWidths = new int[]{0};
                gbl_nestedPanel3.rowHeights = new int[]{0, 0, 0, 0};
                gbl_nestedPanel3.columnWeights = new double[]{0.0};
                gbl_nestedPanel3.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0};
                nestedPanel3.setLayout(gbl_nestedPanel3);

                detectionZoneLabel = new JLabel("label");
                GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
                gbc_lblNewLabel.anchor = GridBagConstraints.WEST;
                gbc_lblNewLabel.insets = new Insets(0, 0, 1, 0);
                gbc_lblNewLabel.gridx = 0;
                gbc_lblNewLabel.gridy = 0;
                nestedPanel3.add(detectionZoneLabel, gbc_lblNewLabel);

                scrollPane_2 = new JScrollPane();
                GridBagConstraints gbc_scrollPane_2 = new GridBagConstraints();
                gbc_scrollPane_2.weighty = 1.0;
                gbc_scrollPane_2.weightx = 1.0;
                gbc_scrollPane_2.fill = GridBagConstraints.BOTH;
                gbc_scrollPane_2.gridx = 0;
                gbc_scrollPane_2.gridy = 1;
                nestedPanel3.add(scrollPane_2, gbc_scrollPane_2);

                txtrDetectionZone = new JTextArea();
                scrollPane_2.setViewportView(txtrDetectionZone);

                relevanceZoneLabel = new JLabel("label");
                GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
                gbc_lblNewLabel_1.anchor = GridBagConstraints.WEST;
                gbc_lblNewLabel_1.insets = new Insets(5, 0, 1, 0);
                gbc_lblNewLabel_1.gridx = 0;
                gbc_lblNewLabel_1.gridy = 2;
                nestedPanel3.add(relevanceZoneLabel, gbc_lblNewLabel_1);

                scrollPane_1 = new JScrollPane();
                GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
                gbc_scrollPane_1.weighty = 1.0;
                gbc_scrollPane_1.weightx = 1.0;
                gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
                gbc_scrollPane_1.gridx = 0;
                gbc_scrollPane_1.gridy = 3;
                nestedPanel3.add(scrollPane_1, gbc_scrollPane_1);

                txtrRelevanceZone = new JTextArea();
                scrollPane_1.setViewportView(txtrRelevanceZone);

                nestedPanel5 = new JPanel();
                nestedPanel5.setBorder(new TitledBorder(null, "Messages", TitledBorder.LEADING, TitledBorder.TOP, null, null));
                GridBagConstraints gbc_nestedPanel5 = new GridBagConstraints();
                gbc_nestedPanel5.weighty = 1.0;
                gbc_nestedPanel5.weightx = 1.0;
                gbc_nestedPanel5.fill = GridBagConstraints.BOTH;
                gbc_nestedPanel5.gridwidth = 2;
                gbc_nestedPanel5.insets = new Insets(10, 10, 10, 10);
                gbc_nestedPanel5.gridx = 1;
                gbc_nestedPanel5.gridy = 2;
                panel.add(nestedPanel5, gbc_nestedPanel5);
                GridBagLayout gbl_nestedPanel5 = new GridBagLayout();
                gbl_nestedPanel5.columnWidths = new int[]{0, 0};
                gbl_nestedPanel5.rowHeights = new int[]{0, 0};
                gbl_nestedPanel5.columnWeights = new double[]{0.0, 0.0};
                gbl_nestedPanel5.rowWeights = new double[]{0.0, 0.0};
                nestedPanel5.setLayout(gbl_nestedPanel5);

                for(int index = 0 ; index < 4; index++) {
                    nstPanel[index] = new SignalingMessagePane();
                    nstPanel[index].initialize();
                    GridBagConstraints gbc_nst5Panel1 = new GridBagConstraints();
                    gbc_nst5Panel1.weighty = 0.5;
                    gbc_nst5Panel1.weightx = 0.5;
                    gbc_nst5Panel1.insets = new Insets(5, 5, 5, 10);
                    gbc_nst5Panel1.fill = GridBagConstraints.BOTH;
                    gbc_nst5Panel1.gridx = index % 2;
                    gbc_nst5Panel1.gridy = index > 1? 1:0;
                    nestedPanel5.add(nstPanel[index], gbc_nst5Panel1);
                }
    }

}

How can I avoid this behaviour? What am I doing wrong?

Body:
Change this line of the code you posted:

txtrDetectionZone = new JTextArea();

Give the JTextArea an initial size by using the constructor that takes the number of rows and columns, e.g.

txtrDetectionZone = new JTextArea(10, 50);

Also you can set the scrollbar policy so that the scrollbars always appear, e.g.

scrollPane_2 = new JScrollPane(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);

That way, the scrollbars will not appear and disappear.


问:
How to get more group matches after specific string?
How it is possible to get more groups of regular expression?

I want to extract substrings of following string:

```<code>group g1 l1 l2 l3 g2 g3.l1
</code>```

as groups. The output should include g1, l1, l2, l3, g2 and g3.l1.

I already tried to get these with regular expressions like this:

```<code>group (\S+)\s(\S+)*
</code>```

My problem is, that I could get different groups with the group expression ( ), but I can get more or less of these substrings. My string also could like this: group g1 g2.l1

答:
Your pattern starts with matching group and then uses 2 capturing groups. You get only 2 groups because the repetition in the last group repeats matching only a non whitespace char \S and will not match a whitespace char.

If you would change that to (\s\S+)* you will repeat the capturing group capturing only the value of the last repetition.

What you might do is making use of \G to get repetetive matches by asserting the position at the end of the previous match

```<code>(?:^group |\G(?!^))(\S+)(?:\s+|$)
</code>```

In java

```<code>String regex = "(?:^group |\\G(?!^))(\\S+)(?:\\s+|$)";
</code>```

That will match

(?: Non capturing group

^group Match group and a space at the string of the string

| Or

\G(?!^) Assert position at the end of the previous match, not at the start of the string

) Close non capturing group

(\S+) Capture in group 1 matching 1+ non whitespace chars

(?:\s+|$) Match either 1+ whitespace chars or assert end of string

Regex demo | Java demo

For example

```<code>String regex = "(?:^group |\\G(?!^))(\\S+)(?:\\s+|$)";
String string = "group g1 l1 l2 l3 g2 g3.l1";

Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println(matcher.group(1));
}
</code>```

Result

```<code>g1
l1
l2
l3
g2
g3.l1
</code>```

Body:
How it is possible to get more groups of regular expression?

I want to extract substrings of following string:

group g1 l1 l2 l3 g2 g3.l1

as groups. The output should include g1, l1, l2, l3, g2 and g3.l1.

I already tried to get these with regular expressions like this:

group (\S+)\s(\S+)*

My problem is, that I could get different groups with the group expression ( ), but I can get more or less of these substrings. My string also could like this: group g1 g2.l1

Body:
Your pattern starts with matching group and then uses 2 capturing groups. You get only 2 groups because the repetition in the last group repeats matching only a non whitespace char \S and will not match a whitespace char.

If you would change that to (\s\S+)* you will repeat the capturing group capturing only the value of the last repetition.

What you might do is making use of \G to get repetetive matches by asserting the position at the end of the previous match

(?:^group |\G(?!^))(\S+)(?:\s+|$)

In java

String regex = "(?:^group |\\G(?!^))(\\S+)(?:\\s+|$)";

That will match

(?: Non capturing group

^group Match group and a space at the string of the string

| Or

\G(?!^) Assert position at the end of the previous match, not at the start of the string

) Close non capturing group

(\S+) Capture in group 1 matching 1+ non whitespace chars

(?:\s+|$) Match either 1+ whitespace chars or assert end of string

Regex demo | Java demo

For example

String regex = "(?:^group |\\G(?!^))(\\S+)(?:\\s+|$)";
String string = "group g1 l1 l2 l3 g2 g3.l1";

Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);

while (matcher.find()) {
    System.out.println(matcher.group(1));
}

Result

g1
l1
l2
l3
g2
g3.l1


问:
Elasticsearch Synonym search using wordnet not working
I tried to debug my synonym search .it seems like when i use wornet format and use the wn_s.pl file it doesn't work, but when i use a custom synonym.txt file then it works.Please let me know where i am doing wrong.please find my below index:

```<code>{
    "settings": {
        "index": {
            "analysis": {
                "filter": {
                    "synonym": {
                        "type": "synonym",
                        "format": "wordnet",
                        "synonyms_path": "analysis/wn_s.pl"
                    }

                },
                "analyzer": {
                    "synonym": {
                        "tokenizer": "standard",
                        "filter": ["lowercase",
                            "synonym"
                        ]
                    }

                },
                "mappings": {
                    "properties": {
                        "firebaseId": {
                            "type": "text"
                        },
                        "name": {
                            "fielddata": true,
                            "type": "text",
                            "analyzer": "standard"
                        },
                        "name_auto": {
                            "type": "text"
                        },

                        "category_name": {
                            "type": "text",
                            "analyzer": "synonym"

                        },
                        "sku": {
                            "type": "text"
                        },
                        "price": {
                            "type": "text"
                        },
                        "magento_id": {
                            "type": "text"
                        },
                        "seller_id": {
                            "type": "text"
                        },
                        "square_item_id": {
                            "type": "text"
                        },
                        "square_variation_id": {
                            "type": "text"
                        },
                        "typeId": {
                            "type": "text"
                        }
                    }
                }
            }
        }
    }
}
</code>```

I am trying to do synonym search on category_name ,i have items like shoes and dress etc .when i search for boots,flipflop or slipper nothing comes.

here is my query search:

```<code>{
    "query": {
        "match": {
            "category_name": "flipflop"
        }
    }
}
</code>```

答:
Your wordnet synonym format is not correct. Please have a look here
For a fast implementation please look at the synonyms.json</p>

Body:
I tried to debug my synonym search .it seems like when i use wornet format and use the wn_s.pl file it doesn't work, but when i use a custom synonym.txt file then it works.Please let me know where i am doing wrong.please find my below index:

{
    "settings": {
        "index": {
            "analysis": {
                "filter": {
                    "synonym": {
                        "type": "synonym",
                        "format": "wordnet",
                        "synonyms_path": "analysis/wn_s.pl"
                    }

                },
                "analyzer": {
                    "synonym": {
                        "tokenizer": "standard",
                        "filter": ["lowercase",
                            "synonym"
                        ]
                    }

                },
                "mappings": {
                    "properties": {
                        "firebaseId": {
                            "type": "text"
                        },
                        "name": {
                            "fielddata": true,
                            "type": "text",
                            "analyzer": "standard"
                        },
                        "name_auto": {
                            "type": "text"
                        },

                        "category_name": {
                            "type": "text",
                            "analyzer": "synonym"

                        },
                        "sku": {
                            "type": "text"
                        },
                        "price": {
                            "type": "text"
                        },
                        "magento_id": {
                            "type": "text"
                        },
                        "seller_id": {
                            "type": "text"
                        },
                        "square_item_id": {
                            "type": "text"
                        },
                        "square_variation_id": {
                            "type": "text"
                        },
                        "typeId": {
                            "type": "text"
                        }
                    }
                }
            }
        }
    }
}

I am trying to do synonym search on category_name ,i have items like shoes and dress etc .when i search for boots,flipflop or slipper nothing comes.

here is my query search:

{
    "query": {
        "match": {
            "category_name": "flipflop"
        }
    }
}


问:
LiveData two-way databinding WITHOUT exposing MutableLiveData
I'm trying to use two-way databinding on a EditText, that works fine if I expose the field as MutableLiveData as it is usually seen on examples I found online.

However there are good reasons not to expose MutableLiveData and those reasons aren't magically invalid because I decided to use the databinding library.

EDIT: The main motivation here is MyViewModel should remain in control of setting data (this is the reason why it is not recommended to expose MutableLiveData directly), in the setter I can perform whatever checks or transformations necessary and then just call setValue on the LiveData.

I usually expose a LiveData getter and a separate setter from my ViewModel, I tried to get this working with two-way data binding by using the InverseMethod() annotation, but that won't really work because databinding is looking for a InverseMethod to getValue() of the LiveData itself.

Here is a simple example:

```<code>public class MyViewModel extends ViewModel {

    private MutableLiveData<String> mEmail = new MutableLiveData<>();

    // @InverseMethod("setEmail")    ### THIS DOESN'T WORK
    public LiveData<String> getEmail() {
        return mEmail;
    }

    // ### I WANT DATA-BINDING TO USE THIS METHOD
    public void setEmail(String email) {
        if (mEmail.getValue() != email) {
            mEmail.setValue(email);
        }
    }
}
</code>```

and this how a want to bind it

```<code><EditText
   android:id="@+id/input_email"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:text="@={viewmodel.email}"/>
</code>```

the only workaround so far that works is using one-way data-binding to set the text on the EditText and then attach a TextWatcher and call my ViewModel.setter from there.

EDIT:

second workaround is to extend MutableLiveData and then do the checks and transformations in an overridden setValue ... that's a lot of boilerplate to write.

答:
I had exactly the same question, that´s how i found yours.
I know it´s not exactly what you are looking for but an option would be to observe mEmail from your ViewModel, and implement your setEmail() code in it (after the value itself has been set of course... i don´t know how to control setting the value which is what you are looking for i guess)</p>

```<code>val observer = Observer<String> { setEmail(it)}
fun setEmail(value:String){ //Your code }
init{
    mEmail.observeForever(observer)
}
//Don´t forget to remove the observer
</code>```

Body:
I'm trying to use two-way databinding on a EditText, that works fine if I expose the field as MutableLiveData as it is usually seen on examples I found online.

However there are good reasons not to expose MutableLiveData and those reasons aren't magically invalid because I decided to use the databinding library.

EDIT: The main motivation here is MyViewModel should remain in control of setting data (this is the reason why it is not recommended to expose MutableLiveData directly), in the setter I can perform whatever checks or transformations necessary and then just call setValue on the LiveData.

I usually expose a LiveData getter and a separate setter from my ViewModel, I tried to get this working with two-way data binding by using the InverseMethod() annotation, but that won't really work because databinding is looking for a InverseMethod to getValue() of the LiveData itself.

Here is a simple example:

public class MyViewModel extends ViewModel {

    private MutableLiveData<String> mEmail = new MutableLiveData<>();

    // @InverseMethod("setEmail")    ### THIS DOESN'T WORK
    public LiveData<String> getEmail() {
        return mEmail;
    }

    // ### I WANT DATA-BINDING TO USE THIS METHOD
    public void setEmail(String email) {
        if (mEmail.getValue() != email) {
            mEmail.setValue(email);
        }
    }
}

and this how a want to bind it

<EditText
   android:id="@+id/input_email"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:text="@={viewmodel.email}"/>

the only workaround so far that works is using one-way data-binding to set the text on the EditText and then attach a TextWatcher and call my ViewModel.setter from there.

EDIT:

second workaround is to extend MutableLiveData and then do the checks and transformations in an overridden setValue ... that's a lot of boilerplate to write.

Body:
I had exactly the same question, that´s how i found yours.
I know it´s not exactly what you are looking for but an option would be to observe mEmail from your ViewModel, and implement your setEmail() code in it (after the value itself has been set of course... i don´t know how to control setting the value which is what you are looking for i guess)

val observer = Observer<String> { setEmail(it)}
fun setEmail(value:String){ //Your code }
init{
    mEmail.observeForever(observer)
}
//Don´t forget to remove the observer