问:
Error occurred in the mediation of the class mediator WSO2 ESB
I used wso2 esb 5.0 for create proxy services. I created proxy service using class mediator. Below is the java class.

```<code>public class CalculatePaymentAmount extends AbstractMediator {

    public boolean mediate(MessageContext messageContext) {

        String noOfMonths = messageContext.getEnvelope().getBody().getFirstElement().
                getFirstChildWithName(new QName("noOfMonths")).getText();

        String InsuranceRate = messageContext.getEnvelope().getBody().getFirstElement().
                getFirstChildWithName(new QName("InsuranceRate")).getText();

        DecimalFormat decimalFormat = new DecimalFormat("#.##");

        double totalAmount = Double.parseDouble(noOfMonths) * Double.parseDouble(InsuranceRate);

        messageContext.setProperty("noOfMonths", noOfMonths);
        messageContext.setProperty("paymentAmount", decimalFormat.format(totalAmount));

        return true;
    }

    public String getType() {
        return null;
    }

    public void setTraceState(int traceState) {
        traceState = 0;
    }

    public int getTraceState() {
        return 0;
    }

}
</code>```

I created the proxy service using class mediator. Below define the proxy code.

```<code><?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="PaymentAmountProxy"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http,https">
   <target>
      <inSequence>
         <log/>
         <class name="com.mediator.java.CalculatePaymentAmount"/>
         <property expression="get-property('default','noOfMonths')"
                   name="getNoOfMonths"
                   scope="default"
                   type="STRING"/>
         <property expression="get-property('default','paymentAmount')"
                   name="getPaymentAmount"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','getNoOfMonths')"
                      name="No.Of Months:"/>
            <property expression="get-property('default','getPaymentAmount')"
                      name="Paymrent Amount:"/>
         </log>
      </inSequence>
   </target>
   <description/>
</proxy>
</code>```

This one working fine and gave expected response.
But when I use this class mediator with other mediators, it getting errors when I invoked the proxy service.
Below mentioned the proxy service that I used with class mediator.

```<code><?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="LatestLicenseRenewalSystem"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http,https">
   <target>
      <inSequence>
         <log/>
         <property expression="get-property('transport','VehicleNo')"
                   name="vehicleNo"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','vehicleNo')" name="VehicleNo"/>
         </log>
         <payloadFactory media-type="xml">
            <format>
               <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                                 xmlns:wsa="http://www.w3.org/2005/08/addressing"
                                 xmlns:sam="http://sample.esb.org">
                  <soapenv:Header/>
                  <soapenv:Body>
                     <sam:getPolicyID>
                        <sam:vehicleNumber>$1</sam:vehicleNumber>
                     </sam:getPolicyID>
                  </soapenv:Body>
               </soapenv:Envelope>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('default','vehicleNo')"/>
            </args>
         </payloadFactory>
         <log level="full"/>
         <header name="Action" scope="default" value="urn:getCertificateID"/>
         <call>
            <endpoint>
               <address format="soap12"
                        uri="http://172.17.0.1:9763/services/EmissionTestService.EmissionTestServiceHttpSoap12Endpoint/">
                  <enableAddressing/>
               </address>
            </endpoint>
         </call>
         <log level="full"/>
         <property xmlns:ns="http://sample.esb.org"
                   expression="//ns:getCertificateIDResponse/ns:return"
                   name="certificateID"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','certificateID')"
                      name="CertificateID"/>
         </log>
         <class name="com.mediator.java.CalculatePaymentAmount"/>
         <property expression="get-property('default','noOfMonths')"
                   name="getNoOfMonths"
                   scope="default"
                   type="STRING"/>
         <property expression="get-property('default','paymentAmount')"
                   name="getPaymentAmount"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','getNoOfMonths')"
                      name="No.Of Months:"/>
            <property expression="get-property('default','getPaymentAmount')"
                      name="Paymrent Amount:"/>
         </log>
         <respond/>
      </inSequence>
   </target>
   <description/>
</proxy>
</code>```

Below error is occurred when invoking the above proxy service.

```<code>LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: urn:getCertificateIDResponse, SOAPAction: urn:getCertificateIDResponse, ReplyTo: http://www.w3.org/2005/08/addressing/anonymous, MessageID: urn:uuid:6f4557eb-b8ff-4c19-bbe8-4c7e929d8386, Direction: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = Error occured in the mediation of the class mediator, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>urn:getCertificateIDResponse</wsa:Action><wsa:RelatesTo>urn:uuid:6f4557eb-b8ff-4c19-bbe8-4c7e929d8386</wsa:RelatesTo></soapenv:Header><soapenv:Body><ns:getCertificateIDResponse xmlns:ns="http://sample.esb.org"><ns:return>-1250719063</ns:return></ns:getCertificateIDResponse></soapenv:Body></soapenv:Envelope>
</code>```

Can anyone help me to solve this. Any help or workarounds are really appreciated.

答:
Your class mediator is accessing the elements 'noOfMonths' and 'InsuranceRate' from the message context. But according to the error log, the message context is having a different soap envelope which does not have the above elements.

```<code><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>urn:getCertificateIDResponse</wsa:Action><wsa:RelatesTo>urn:uuid:6f4557eb-b8ff-4c19-bbe8-4c7e929d8386</wsa:RelatesTo></soapenv:Header><soapenv:Body><ns:getCertificateIDResponse xmlns:ns="http://sample.esb.org"><ns:return>-1250719063</ns:return></ns:getCertificateIDResponse></soapenv:Body></soapenv:Envelope>
</code>```

This must me the response received from the call operation before the class mediator.

You have to either isolate the class mediator from the call operation and use different proxy services or move the class mediator above the payload factory.

Body:
I used wso2 esb 5.0 for create proxy services. I created proxy service using class mediator. Below is the java class.

public class CalculatePaymentAmount extends AbstractMediator {

    public boolean mediate(MessageContext messageContext) {

        String noOfMonths = messageContext.getEnvelope().getBody().getFirstElement().
                getFirstChildWithName(new QName("noOfMonths")).getText();

        String InsuranceRate = messageContext.getEnvelope().getBody().getFirstElement().
                getFirstChildWithName(new QName("InsuranceRate")).getText();

        DecimalFormat decimalFormat = new DecimalFormat("#.##");

        double totalAmount = Double.parseDouble(noOfMonths) * Double.parseDouble(InsuranceRate);

        messageContext.setProperty("noOfMonths", noOfMonths);
        messageContext.setProperty("paymentAmount", decimalFormat.format(totalAmount));

        return true;
    }

    public String getType() {
        return null;
    }

    public void setTraceState(int traceState) {
        traceState = 0;
    }

    public int getTraceState() {
        return 0;
    }

}

I created the proxy service using class mediator. Below define the proxy code.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="PaymentAmountProxy"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http,https">
   <target>
      <inSequence>
         <log/>
         <class name="com.mediator.java.CalculatePaymentAmount"/>
         <property expression="get-property('default','noOfMonths')"
                   name="getNoOfMonths"
                   scope="default"
                   type="STRING"/>
         <property expression="get-property('default','paymentAmount')"
                   name="getPaymentAmount"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','getNoOfMonths')"
                      name="No.Of Months:"/>
            <property expression="get-property('default','getPaymentAmount')"
                      name="Paymrent Amount:"/>
         </log>
      </inSequence>
   </target>
   <description/>
</proxy>

This one working fine and gave expected response.
But when I use this class mediator with other mediators, it getting errors when I invoked the proxy service.
Below mentioned the proxy service that I used with class mediator.

<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
       name="LatestLicenseRenewalSystem"
       startOnLoad="true"
       statistics="disable"
       trace="disable"
       transports="http,https">
   <target>
      <inSequence>
         <log/>
         <property expression="get-property('transport','VehicleNo')"
                   name="vehicleNo"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','vehicleNo')" name="VehicleNo"/>
         </log>
         <payloadFactory media-type="xml">
            <format>
               <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                                 xmlns:wsa="http://www.w3.org/2005/08/addressing"
                                 xmlns:sam="http://sample.esb.org">
                  <soapenv:Header/>
                  <soapenv:Body>
                     <sam:getPolicyID>
                        <sam:vehicleNumber>$1</sam:vehicleNumber>
                     </sam:getPolicyID>
                  </soapenv:Body>
               </soapenv:Envelope>
            </format>
            <args>
               <arg evaluator="xml" expression="get-property('default','vehicleNo')"/>
            </args>
         </payloadFactory>
         <log level="full"/>

         <call>
            <endpoint>
               <address format="soap12"
                        uri="http://172.17.0.1:9763/services/EmissionTestService.EmissionTestServiceHttpSoap12Endpoint/">
                  <enableAddressing/>
               </address>
            </endpoint>
         </call>
         <log level="full"/>
         <property xmlns:ns="http://sample.esb.org"
                   expression="//ns:getCertificateIDResponse/ns:return"
                   name="certificateID"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','certificateID')"
                      name="CertificateID"/>
         </log>
         <class name="com.mediator.java.CalculatePaymentAmount"/>
         <property expression="get-property('default','noOfMonths')"
                   name="getNoOfMonths"
                   scope="default"
                   type="STRING"/>
         <property expression="get-property('default','paymentAmount')"
                   name="getPaymentAmount"
                   scope="default"
                   type="STRING"/>
         <log>
            <property expression="get-property('default','getNoOfMonths')"
                      name="No.Of Months:"/>
            <property expression="get-property('default','getPaymentAmount')"
                      name="Paymrent Amount:"/>
         </log>
         <respond/>
      </inSequence>
   </target>
   <description/>
</proxy>

Below error is occurred when invoking the above proxy service.

LogMediator To: http://www.w3.org/2005/08/addressing/anonymous, WSAction: urn:getCertificateIDResponse, SOAPAction: urn:getCertificateIDResponse, ReplyTo: http://www.w3.org/2005/08/addressing/anonymous, MessageID: urn:uuid:6f4557eb-b8ff-4c19-bbe8-4c7e929d8386, Direction: request, MESSAGE = Executing default 'fault' sequence, ERROR_CODE = 0, ERROR_MESSAGE = Error occured in the mediation of the class mediator, Envelope: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>urn:getCertificateIDResponse</wsa:Action><wsa:RelatesTo>urn:uuid:6f4557eb-b8ff-4c19-bbe8-4c7e929d8386</wsa:RelatesTo></soapenv:Header><soapenv:Body><ns:getCertificateIDResponse xmlns:ns="http://sample.esb.org"><ns:return>-1250719063</ns:return></ns:getCertificateIDResponse></soapenv:Body></soapenv:Envelope>

Can anyone help me to solve this. Any help or workarounds are really appreciated.

Body:
Your class mediator is accessing the elements 'noOfMonths' and 'InsuranceRate' from the message context. But according to the error log, the message context is having a different soap envelope which does not have the above elements.

<soapenv:Envelope xmlns:soapenv="http://www.w3.org/2003/05/soap-envelope"><soapenv:Header xmlns:wsa="http://www.w3.org/2005/08/addressing"><wsa:Action>urn:getCertificateIDResponse</wsa:Action><wsa:RelatesTo>urn:uuid:6f4557eb-b8ff-4c19-bbe8-4c7e929d8386</wsa:RelatesTo></soapenv:Header><soapenv:Body><ns:getCertificateIDResponse xmlns:ns="http://sample.esb.org"><ns:return>-1250719063</ns:return></ns:getCertificateIDResponse></soapenv:Body></soapenv:Envelope>

This must me the response received from the call operation before the class mediator.

You have to either isolate the class mediator from the call operation and use different proxy services or move the class mediator above the payload factory.


来源: stackexchange

问:
SPARQL DBPedia query for seating capacity, optimize and remove duplicates
I want to get all objects with seating capacity information on DBPedia. Optionally, I want to get their label, address, lat and lon information.

My issue is that I get a lot of duplicates even after filtering by language. How can I get distinct entries based on, say, 'address', or any other attribute?

Also, can you tell which part of this query can be improved so that my query doesn't time out when I use the public DBpedia endpoint? Thanks!

```<code>PREFIX dbpediaO: <http://dbpedia.org/ontology/>

SELECT ?place ?label ?capacity ?address ?lat ?lon WHERE {

?place dbpedia2:seatingCapacity ?capacity .

OPTIONAL{

?place dbpediaO:address ?address .
?place rdfs:label ?label .
?plage geo:lat ?lat .
?place geo:long ?lon .
    }

filter (lang(?label) = "en" || lang(?label) = "eng")
filter (lang(?address) = "en" || lang(?address) = "eng")

}
</code>```

答:
Your places have multiple values of, for example, address. The unique thing is the URI itself. Moreover, you should put each property in a separate OPTIONAL, or at least use separate OPTIONAL clauses for lat/long. For label you do not need an OPTIONAL clause at all in DBpedia. The only way to get unique places is to group by the place and sample or group_concat all other properties. Something like this:

```<code>PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?place (sample(?_label) as ?label)
(group_concat(?capacity; separator=";") as ?capacities)
(group_concat(?address; separator=";") as ?adresses) ?lat ?lon
WHERE {
  ?place dbo:seatingCapacity ?capacity ;
         rdfs:label ?_label .
  filter (langmatches(lang(?_label),"en"))
  OPTIONAL {
       ?place dbo:address ?address .
       filter (langmatches(lang(?address), "en"))
  } OPTIONAL {
       ?place geo:lat ?lat ; geo:long ?lon .
  }
}
group by ?place ?lat ?lon
order by desc(?place)
limit 100
</code>```

As you can see, there are also multiple capacity values for places.

ContentLicense: CC BY-SA 4.0

Body:
I want to get all objects with seating capacity information on DBPedia. Optionally, I want to get their label, address, lat and lon information.

My issue is that I get a lot of duplicates even after filtering by language. How can I get distinct entries based on, say, 'address', or any other attribute?

Also, can you tell which part of this query can be improved so that my query doesn't time out when I use the public <a href="http://dbpedia.org/snorql/?query=%0D%0APREFIX%20dbpediaO%3A%20%3Chttp%3A%2F%2Fdbpedia.org%2Fontology%2F%3E%0D%0A%0D%0ASELECT%20DISTINCT%28%3Fplace%29%20WHERE%20%7B%0D%0A%0D%0A%3Fplace%20dbpedia2%3AseatingCapacity%20%3Fcapacity%20.%0D%0A%0D%0A%0D%0AOPTIONAL%7B%0D%0A%0D%0A%3Fplace%20dbpediaO%3Aaddress%20%3Faddress%20.%20%0D%0A%3Fplace%20rdfs%3Alabel%20%3Flabel%20.%0D%0A%3Fplage%20geo%3Alat%20%3Flat%20.%0D%0A%3Fplace%20geo%3Along%20%3Flon%20.%0D%0A%20%20%20%20%7D%0D%0A%0D%0Afilter%20%28lang%28%3Flabel%29%20%3D%20%22en%22%20%7C%7C%20lang%28%3Flabel%29%20%3D%20%22eng%22%29%0D%0Afilter%20%28lang%28%3Faddress%29%20%3D%20%22en%22%20%7C%7C%20lang%28%3Faddress%29%20%3D%20%22eng%22%29%0D%0A%0D%0A%7D%0D%0A%0D%0A%0D%0ALIMIT%2010%0D%0A%0D%0A" rel="nofollow noreferrer">DBpedia endpoint? Thanks!

PREFIX dbpediaO: <http://dbpedia.org/ontology/>

SELECT ?place ?label ?capacity ?address ?lat ?lon WHERE {

?place dbpedia2:seatingCapacity ?capacity .

OPTIONAL{

?place dbpediaO:address ?address .
?place rdfs:label ?label .
?plage geo:lat ?lat .
?place geo:long ?lon .
    }

filter (lang(?label) = "en" || lang(?label) = "eng")
filter (lang(?address) = "en" || lang(?address) = "eng")

}

Body:
Your places have multiple values of, for example, address. The unique thing is the URI itself. Moreover, you should put each property in a separate OPTIONAL, or at least use separate OPTIONAL clauses for lat/long. For label you do not need an OPTIONAL clause at all in DBpedia. The only way to get unique places is to group by the place and sample or group_concat all other properties. Something like this:

PREFIX dbo: <http://dbpedia.org/ontology/>
SELECT ?place (sample(?_label) as ?label)
(group_concat(?capacity; separator=";") as ?capacities)
(group_concat(?address; separator=";") as ?adresses) ?lat ?lon
WHERE {
  ?place dbo:seatingCapacity ?capacity ;
         rdfs:label ?_label .
  filter (langmatches(lang(?_label),"en"))
  OPTIONAL {
       ?place dbo:address ?address .
       filter (langmatches(lang(?address), "en"))
  } OPTIONAL {
       ?place geo:lat ?lat ; geo:long ?lon .
  }
}
group by ?place ?lat ?lon
order by desc(?place)
limit 100

As you can see, there are also multiple capacity values for places.


问:
Laravel 5.1 event fire
I'm firing event and passing object with array like this:

```<code>$event = new App\Events\SendMessage;
$event->msg = [ 'sender_id'=>'191',
                'recepient_id'=>'190',
                'text'=>'some text',
              ];
Event::fire($event);
</code>```

Is it possible to make this call a bit shorter and fire event in one line like this?

```<code>Event::fire(new App\Events\SendMessage([
                        'sender_id'=>'191',
                        'recepient_id'=>'190',
                        'text'=>'some text',
                    ]));
</code>```

答:
you can fire event like this in laravel

just put the code into your controller

```<code>event(new App\Events\EventClassName());
</code>```

if your Event has parameters then

```<code>event(new App\Events\EventClassName(['first' => 'value','second' => 'value']));
</code>```

ContentLicense: CC BY-SA 3.0

Title: Laravel 5.1 event fire

Body:
I'm firing event and passing object with array like this:

$event = new App\Events\SendMessage;
$event->msg = [ 'sender_id'=>'191',
                'recepient_id'=>'190',
                'text'=>'some text',
              ];
Event::fire($event);

Is it possible to make this call a bit shorter and fire event in one line like this?

Event::fire(new App\Events\SendMessage([
                        'sender_id'=>'191',
                        'recepient_id'=>'190',
                        'text'=>'some text',
                    ]));

Body:
you can fire event like this in laravel

just put the code into your controller

event(new App\Events\EventClassName());

if your Event has parameters then

event(new App\Events\EventClassName(['first' => 'value','second' => 'value']));


问:
Compare two files and create a new one with the differences
I need to compare two files and create a new one with the differences of this two, i just know compare the files to show if they are equal or not, but i dont know how can i solve my problem.

I search so much info on how to compare files, but i didnt found the way of display the differences between this two files. This is my actual code.

Edit: The file can contain more than 1 line of data, usually like 30.

The text cannot be deleted, and the similarity just appear in the end of the text. I mean, the final line of a file text will be always the start of the other file text.

This is for homework and the instruction are: "Read the host file and check if any line is already present in the ip url file, and in case they are not, it is necessary to write them in a temporary file."

```<code>#include <stdio.h>
void main()
{
FILE *f1, *f2;
int a, b;

f1 = fopen("D:\\product3\\test.txt","r");
f2 = fopen("D:\\product3\\test2.txt", "r");

if(f1 == NULL || f2 == NULL)
{
    printf("Cannot read the files");
}
else
{
    a = getc(f1);
    b = getc(f2);

    while (a != EOF && b != EOF)
    {
        a = getc(f1);
        b = getc(f2);

        if(a != b)
        {
            printf("");
        }
    }
    if (a == b)
    {
        printf("\n The files are equal \n");
    }
    else if (a!=b)
    {
        printf("\n The files aren't equal \n");
    }
    else
    {
        printf("\n Error \n");
    }
}

fclose(f1);
fclose(f2);
}
</code>```

The content of the files are:

```
>Test.txt
AAA
aaa
bbb
BBB
111

>Test2.txt
AAA
aaa
bbb
BBB
111
333
444
555
6666
777
CCC
```

so the output must be:

```
>333
444
555
6666
777
CCC
```

答:
Well, your algorithm is wrong. Here is some pseudo code that might help:</p>

```<code>function line_exists(l, la)
    for line in la
        if line == l
            return true
    return false

line_array = array()

for line in file1
    line_array.add(line)

for line in file2
    if not line_exists(line, line_array)
        print(line)
</code>```

Body:
I need to compare two files and create a new one with the differences of this two, i just know compare the files to show if they are equal or not, but i dont know how can i solve my problem.

I search so much info on how to compare files, but i didnt found the way of display the differences between this two files. This is my actual code.

Edit: The file can contain more than 1 line of data, usually like 30.

The text cannot be deleted, and the similarity just appear in the end of the text. I mean, the final line of a file text will be always the start of the other file text.

This is for homework and the instruction are: "Read the host file and check if any line is already present in the ip url file, and in case they are not, it is necessary to write them in a temporary file."

#include <stdio.h>
void main()
{
FILE *f1, *f2;
int a, b;

f1 = fopen("D:\\product3\\test.txt","r");
f2 = fopen("D:\\product3\\test2.txt", "r");

if(f1 == NULL || f2 == NULL)
{
    printf("Cannot read the files");
}
else
{
    a = getc(f1);
    b = getc(f2);

    while (a != EOF && b != EOF)
    {
        a = getc(f1);
        b = getc(f2);

        if(a != b)
        {
            printf("");
        }
    }
    if (a == b)
    {
        printf("\n The files are equal \n");
    }
    else if (a!=b)
    {
        printf("\n The files aren't equal \n");
    }
    else
    {
        printf("\n Error \n");
    }
}

fclose(f1);
fclose(f2);
}

The content of the files are:

>Test.txt
AAA
aaa
bbb
BBB
111

>Test2.txt
AAA
aaa
bbb
BBB
111
333
444
555
6666
777
CCC

so the output must be:

>333
444
555
6666
777
CCC

Body:
Well, your algorithm is wrong. Here is some pseudo code that might help:

function line_exists(l, la)
    for line in la
        if line == l
            return true
    return false

line_array = array()

for line in file1
    line_array.add(line)

for line in file2
    if not line_exists(line, line_array)
        print(line)


问:
fonts not changing for textviews inside recyclerview items only for whole app
my problem is that any text views inside any items of all recyclerview don't take its font from XML, just shows the original font of the android

only items of all recycler views have this issue, other text views work fine

I have a lot of recycler view around 23 rv and there is more so it's not a good thing to change every text font programmatically
I tried many things with no luck here
any help?

this is an example:
Adaptor view

```<code>import android.content.Context
import android.util.Log

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.ecom.R
import com.ecom.data.model.FabricProduct
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.item_fabric_product.view.*

class CollectionAdaptor(var mList: List<FabricProduct>, var context: Context, val listener: (FabricProduct) -> Unit
) : RecyclerView.Adapter<CollectionViewHolder>() {

    fun updateList(newitems: List<FabricProduct>) {
        mList = newitems
        notifyDataSetChanged()
   }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CollectionViewHolder {return CollectionViewHolder( LayoutInflater.from(context).inflate(R.layout.item_fabric_product,parent,false))
}

    override fun onBindViewHolder(holder: CollectionViewHolder, position: Int) {
        holder.bind(mList[position], listener)

    }

    override fun getItemCount(): Int {
        return mList.size
    }}

class CollectionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(item: FabricProduct, listener: (FabricProduct) -> Unit) = with(itemView) {
        itemView.text_subcategorie_slogan.text = item.slogan
        itemView.text_subcategorie_title.text = item.title
        setOnClickListener { listener(item) }
    }}
</code>```

recyclerview setup

```<code>mFabricProductlist = FakeData.getFabricCollection()

            rootView.rv_collection_subcategory.layoutManager = GridLayoutManager(activity!!.applicationContext, 2)

            mCollectionAdaptor =
                CollectionAdaptor(mFabricProductlist as List<FabricProduct>, activity!!.applicationContext) { //get the selected item here}

     rootView.rv_collection_subcategory.adapter = mCollectionAdaptor
</code>```

inside a fragment_collection.xml

```<code><androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_collection_subcategory"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
    />
</code>```

item.xml

```<code><?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="220dp"
    android:layout_marginStart="15dp"
    android:layout_marginTop="4dp"
    android:layout_marginEnd="15dp"
    android:layout_marginBottom="4dp"

    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_margin="10dp"
        android:layout_marginStart="4dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/text_subcategorie_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="@font/montserrat_bold"
            android:shadowColor="#000"
            android:shadowDy="1"
            android:shadowRadius="1"
            android:text="000"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/text_subcategorie_slogan"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="@font/montserrat"
            android:shadowColor="#000"
            android:shadowDy="1"
            android:shadowRadius="2"
            android:text="000"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textSize="12sp" />

    </LinearLayout>

</FrameLayout>
</code>```

build.gradle

```<code>implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0-alpha03'
    androidTestImplementation 'androidx.test.espresso:espresso-
    core:3.2.0-alpha03'
    //Navigation
    implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
</code>```

答:
it's working now, the problem was

```<code>mCollectionAdaptor =
                CollectionAdaptor(mFabricProductlist as List<FabricProduct>, activity!!.applicationContext) { //get the selected item here}
</code>```

I passed applicationContext of the activity so the solution just passes the activity

```<code> mCollectionAdaptor =
                    CollectionAdaptor(mFabricProductlist as List<FabricProduct>, activity!!) { //get the selected item here}
</code>```

thanks

Body:
my problem is that any text views inside any items of all recyclerview don't take its font from XML, just shows the original font of the android

only items of all recycler views have this issue, other text views work fine

I have a lot of recycler view around 23 rv and there is more so it's not a good thing to change every text font programmatically
I tried many things with no luck here
any help?

this is an example:
Adaptor view

import android.content.Context
import android.util.Log

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.recyclerview.widget.RecyclerView
import com.ecom.R
import com.ecom.data.model.FabricProduct
import com.squareup.picasso.Picasso
import kotlinx.android.synthetic.main.item_fabric_product.view.*

class CollectionAdaptor(var mList: List<FabricProduct>, var context: Context, val listener: (FabricProduct) -> Unit
) : RecyclerView.Adapter<CollectionViewHolder>() {

    fun updateList(newitems: List<FabricProduct>) {
        mList = newitems
        notifyDataSetChanged()
   }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CollectionViewHolder {return CollectionViewHolder( LayoutInflater.from(context).inflate(R.layout.item_fabric_product,parent,false))
}

    override fun onBindViewHolder(holder: CollectionViewHolder, position: Int) {
        holder.bind(mList[position], listener)

    }

    override fun getItemCount(): Int {
        return mList.size
    }}

class CollectionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    fun bind(item: FabricProduct, listener: (FabricProduct) -> Unit) = with(itemView) {
        itemView.text_subcategorie_slogan.text = item.slogan
        itemView.text_subcategorie_title.text = item.title
        setOnClickListener { listener(item) }
    }}

recyclerview setup

mFabricProductlist = FakeData.getFabricCollection()

            rootView.rv_collection_subcategory.layoutManager = GridLayoutManager(activity!!.applicationContext, 2)

            mCollectionAdaptor =
                CollectionAdaptor(mFabricProductlist as List<FabricProduct>, activity!!.applicationContext) { //get the selected item here}

     rootView.rv_collection_subcategory.adapter = mCollectionAdaptor

inside a fragment_collection.xml

<androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_collection_subcategory"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
    />

item.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="220dp"
    android:layout_marginStart="15dp"
    android:layout_marginTop="4dp"
    android:layout_marginEnd="15dp"
    android:layout_marginBottom="4dp"

    >
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:layout_margin="10dp"
        android:layout_marginStart="4dp"
        android:orientation="vertical">

        <TextView
            android:id="@+id/text_subcategorie_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="@font/montserrat_bold"
            android:shadowColor="#000"
            android:shadowDy="1"
            android:shadowRadius="1"
            android:text="000"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/text_subcategorie_slogan"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="@font/montserrat"
            android:shadowColor="#000"
            android:shadowDy="1"
            android:shadowRadius="2"
            android:text="000"
            android:textAllCaps="false"
            android:textColor="@color/white"
            android:textSize="12sp" />

    </LinearLayout>

</FrameLayout>

build.gradle

implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.0-alpha3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.2.0-alpha03'
    androidTestImplementation 'androidx.test.espresso:espresso-
    core:3.2.0-alpha03'
    //Navigation
    implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.0.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

Body:
it's working now, the problem was

mCollectionAdaptor =
                CollectionAdaptor(mFabricProductlist as List<FabricProduct>, activity!!.applicationContext) { //get the selected item here}

I passed applicationContext of the activity so the solution just passes the activity

 mCollectionAdaptor =
                    CollectionAdaptor(mFabricProductlist as List<FabricProduct>, activity!!) { //get the selected item here}

thanks


问:
Get User Agent in my app which doesn't contain a webview
I can ask WebView.getWebSettings().getUserAgentString() to get the user
agent, but this doesn't work all that well for my app as I need to
instantiate a WebView first even though I don't need.

Is there another way to get to the User Agent without using a WebView.getSetting, because in my application, I don't need a webView?

Help me please

答:
The information of user agent is obtained from the HTTP headers, which depends on what browser is used to initiate the WebView object. Therefore, it doesn't make sense if you only want to get the user agent string without creating a WebView.

A better way might be create a WebView and set its visibility to GONE. After getting the user agent string, destroy it.


问:
I am getting multiple calls from angular to the Post API in Node
I am trying to write a file from the data from the database but I'm getting multiple calls from the angular causing multiple entries of the same data.How can I stop that? And also it is causing to override write file after some time.

I am not getting what exactly should I do. I have tried subscribing thing in service in angular but it was of no help.
component.ts

```<code>import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { NgbModalRef, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { CountryService } from './country.service';
import { ConfigService } from '../config.service';

@Component({
  selector: 'app-country',
  templateUrl: './country.component.html',
  styleUrls: ['./country.component.scss'],
  encapsulation: ViewEncapsulation.None,
  providers: []
})
export class CountryComponent implements OnInit {
  public modalRef: NgbModalRef;
  public form: FormGroup;
  public selectedCountry;
  public countries;
  constructor(public fb: FormBuilder, public toastrService: ToastrService,
    public modalService: NgbModal, public configService: ConfigService,
    public countryService: CountryService) {

  }

  ngOnInit() {
    this.form = this.fb.group({
      country: [null, Validators.compose([Validators.required])],
    });
    this.getCountries();
  }

  public getCountries() {
    this.countryService.getCountries((data) => {
      this.countries = data.countries;
    }, (err) => { });
  }

  public selectCountry(country) {
    this.countryService.selectCountry(country, (resp) => {
    }, (err) => { });
  }
}
</code>```

service.ts

```<code>import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { ConfigService } from '../config.service';
import { ToastrService } from 'ngx-toastr';

@Injectable({
  providedIn: 'root'
})
export class CountryService {
  private setHeaders() {
    const headers = new HttpHeaders({
      'content-type': 'application/json',
    });
    return headers;
  }
  constructor(private configService: ConfigService, public http: HttpClient, public toastrService: ToastrService) { }

  selectCountry(country: any, callback, errCallback) {
       const options = {
      headers: this.setHeaders(),
    };
    this.http.post(this.configService.url + '/selectedCountry', country, options).subscribe((resp: any) => {
      callback(resp);
    }, err => {
      errCallback(err);
    });
  }

  getCountries(callback, errCallback) {
       const options = {
      headers: this.setHeaders(),
    };
    this.http.get(this.configService.url + '/countries', options).subscribe((resp: any) => {
         callback(resp.msg);
    }, err => {
      errCallback(err);
    });
  }

}
</code>```

I want the call to be sent only once, not twice

答:
Change your service method like:

add interface:

```<code>export interface Country{
  id: number;
  name: string;
}
</code>```

Change your method:

```<code>getCountries(): Observable<Country> {
    return this.httpClient
      .get('pass api url here')
      .pipe(
        map((body: any) => body),
        catchError(error => of(error))
      );
  }
</code>```

In your component:

```<code>ngOnInit() {
    this.countryService.getCountries().subscribe(
          (result: Countries) => {
            this.countries = result;
          },
          err => {
            log.debug('get countries error', err);
          }
        );
      }
}
</code>```

Body:
I am trying to write a file from the data from the database but I'm getting multiple calls from the angular causing multiple entries of the same data.How can I stop that? And also it is causing to override write file after some time.

I am not getting what exactly should I do. I have tried subscribing thing in service in angular but it was of no help.
component.ts

import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { NgbModalRef, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { ToastrService } from 'ngx-toastr';
import { CountryService } from './country.service';
import { ConfigService } from '../config.service';

@Component({
  selector: 'app-country',
  templateUrl: './country.component.html',
  styleUrls: ['./country.component.scss'],
  encapsulation: ViewEncapsulation.None,
  providers: []
})
export class CountryComponent implements OnInit {
  public modalRef: NgbModalRef;
  public form: FormGroup;
  public selectedCountry;
  public countries;
  constructor(public fb: FormBuilder, public toastrService: ToastrService,
    public modalService: NgbModal, public configService: ConfigService,
    public countryService: CountryService) {

  }

  ngOnInit() {
    this.form = this.fb.group({
      country: [null, Validators.compose([Validators.required])],
    });
    this.getCountries();
  }

  public getCountries() {
    this.countryService.getCountries((data) => {
      this.countries = data.countries;
    }, (err) => { });
  }

  public selectCountry(country) {
    this.countryService.selectCountry(country, (resp) => {
    }, (err) => { });
  }
}

service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
import { ConfigService } from '../config.service';
import { ToastrService } from 'ngx-toastr';

@Injectable({
  providedIn: 'root'
})
export class CountryService {
  private setHeaders() {
    const headers = new HttpHeaders({
      'content-type': 'application/json',
    });
    return headers;
  }
  constructor(private configService: ConfigService, public http: HttpClient, public toastrService: ToastrService) { }

  selectCountry(country: any, callback, errCallback) {
       const options = {
      headers: this.setHeaders(),
    };
    this.http.post(this.configService.url + '/selectedCountry', country, options).subscribe((resp: any) => {
      callback(resp);
    }, err => {
      errCallback(err);
    });
  }

  getCountries(callback, errCallback) {
       const options = {
      headers: this.setHeaders(),
    };
    this.http.get(this.configService.url + '/countries', options).subscribe((resp: any) => {
         callback(resp.msg);
    }, err => {
      errCallback(err);
    });
  }

}

I want the call to be sent only once, not twice

Body:
Change your service method like:

add interface:

export interface Country{
  id: number;
  name: string;
}

Change your method:

getCountries(): Observable<Country> {
    return this.httpClient
      .get('pass api url here')
      .pipe(
        map((body: any) => body),
        catchError(error => of(error))
      );
  }

In your component:

ngOnInit() {
    this.countryService.getCountries().subscribe(
          (result: Countries) => {
            this.countries = result;
          },
          err => {
            log.debug('get countries error', err);
          }
        );
      }
}


问:
How should be the regex for alphanumeric where alphabet only with combinations of"w" or "d" or "h"
I need the regex to validate the user entered string, the string may be of following formats.

ex: 1w 2d 1h or 2w 1h or 1w 2d. Likewise combinations of numbers and w,d and h.

I am looking for the regex to allow the combinations number and w or d or h.

Is it possible to have a regex like that way?

答:
We can try writing a rudimentary parser to check the input string.

```<code>string input = "1w 2d 1h";
string[] parts = Regex.Split(input, @"\s+");
bool success = true;

if (parts.Length > 3)
{
    success = false;
}
else
{
    Regex regex = new Regex(@"\d+(?:w|d|h)");
    foreach (string part in parts)
    {
        Match match = regex.Match(part);
        if (!match.Success)
        {
            success = false;
        }
    }
}

if (success)
{
    Console.WriteLine("MATCH");
}
else
{
    Console.WriteLine("NO MATCH");
}
</code>```

This answer might carry its own weight if, in your C# application, you also needed to extract the numerical values of each component.

Body:
We can try writing a rudimentary parser to check the input string.

string input = "1w 2d 1h";
string[] parts = Regex.Split(input, @"\s+");
bool success = true;

if (parts.Length > 3)
{
    success = false;
}
else
{
    Regex regex = new Regex(@"\d+(?:w|d|h)");
    foreach (string part in parts)
    {
        Match match = regex.Match(part);
        if (!match.Success)
        {
            success = false;
        }
    }
}

if (success)
{
    Console.WriteLine("MATCH");
}
else
{
    Console.WriteLine("NO MATCH");
}

This answer might carry its own weight if, in your C# application, you also needed to extract the numerical values of each component.


问:
how to output a user selected shape & color, whose location and dimensions depend upon the coordinate location of user clicks
As part of a larger project I'm trying to create a basic UI that will allow a user to click a JButton to select a desired color and then allow that user to click another JButton to designate a shape to be displayed, filled in according to the previously selected color.  I understand that I must make use of action events.

Please note I am referencing this similar question:

GUI Application that allows the user to choose the shape and color of a drawing

My code thus far is:

```<code>import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;

public class GUI extends JFrame implements ActionListener, WindowListener
{
private final JButton circleButton, rectangleButton, redButton;
private final JButton greenButton, blueButton, exitButton;
private final JTextArea textArea;
private final JLabel label1;
private final JPanel colorPane;

private String shapeColor = "black";
private String actualShape = "rectangle";

private static final int ROWS = 2, COLS = 3;

public GUI (String title)
{
    super(title);
    //setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    colorPane = new JPanel();

    label1 = new JLabel("current date here");
    label1.setVerticalAlignment(SwingConstants.BOTTOM);
    label1.setHorizontalAlignment(SwingConstants.LEFT);
    label1.setPreferredSize(new Dimension(200,0));
    getContentPane().add(label1, BorderLayout.WEST);

    colorPane.setLayout(new GridLayout(ROWS,COLS));
    getContentPane().add(colorPane, BorderLayout.CENTER);

    redButton = makeButton("Red");
    colorPane.add(redButton);
    greenButton = makeButton("Green");
    colorPane.add(greenButton);
    blueButton = makeButton("Blue");
    colorPane.add(blueButton);
    rectangleButton = makeButton("Rectangle");
    colorPane.add(rectangleButton);
    circleButton = makeButton("Circle");
    colorPane.add(circleButton);
    exitButton = makeButton("Exit");
    colorPane.add(exitButton);

    textArea = new JTextArea(0,20);
    getContentPane().add(textArea, BorderLayout.EAST);

    pack();
}

public void paint(Graphics g, String color)
{
    if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.BLUE);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.GREEN);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.RED);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.GREEN);
        g.fillRect(50,90,100,50);
    }
    else if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.BLUE);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.RED);
        g.fillOval(50, 180, 55, 55);
    }
}

//method designed to create new JButtons while avoiding code duplication
private JButton makeButton(String text)
{
    JButton b = new JButton(text);
    b.setHorizontalAlignment(SwingConstants.LEFT);
    b.addActionListener(this);
    b.setPreferredSize(new Dimension(125,55));

    return b;
}

@Override
public void windowOpened(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowClosing(WindowEvent e)
{
    System.exit(0);

}

@Override
public void windowClosed(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowIconified(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowDeiconified(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowActivated(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowDeactivated(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void actionPerformed(ActionEvent e)
{
    System.out.println( ( (JButton)e.getSource() ).getText() + " button pressed ");

    if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Red")) )
    {
        setShapeColor("Red");
        System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
        //paint(this.getGraphics());
    }
    else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Blue")) )
    {
        setShapeColor("Blue");
        System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
        //paint(this.getGraphics());
    }

    else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Green")) )
    {
        setShapeColor("Green");
        System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
        //paint(this.getGraphics());
    }

    if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Rectangle")) )
    {
        setActualShape("rectangle");
        System.out.println("selected shape is: " + actualShape + " selected color is: " + shapeColor);
        paint(this.getGraphics(), shapeColor);

    }

    else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Circle")) )
    {
        setActualShape("circle");
        System.out.println("selected shape is: " + actualShape + " selected color is: " + shapeColor);
        paint(this.getGraphics(), shapeColor);
    }

}

public String getShapeColor() {
    return shapeColor;
}

public void setShapeColor(String shapeColor) {
    this.shapeColor = shapeColor;
}

public String getActualShape() {
    return actualShape;
}

public void setActualShape(String actualShape) {
    this.actualShape = actualShape;
}

public static void main(String[] args)
{
    new GUI("My Gui").setVisible(true);
}
</code>```

}

What I've thus far achieved is an output that shows both the selected color as well as the selected shape to be rendered in the selected color.

Furthermore, I've been successful in outputting a shape whose position is hard-coded but whose type (either circle or square) and whose color (red, blue or green), is correctly output as a result of the user clicks.

The final phase, upon which I am struggling, is the implementation of the shape's output so that the user's sequence of clicks determines the location and dimensions of the shape output to the screen.

The goal is to achieve the functionality demonstrated here:

https://metrostate.learn.minnstate.edu/content/2020/4560296-20201000539/ICS372%20-%20Assignment%202%20Video.mp4?d2lSessionVal=ARifwbCHriCBrkgxBWpL9g8fL&ou=4560296

I'm relatively certain that the correct solution is similar to the following code:

```<code>import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

/**
 *  Note: Normally the ButtonPanel and DrawingArea would not be static
classes.
 *  This was done for the convenience of posting the code in one class and
to
 *  highlight the differences between the two approaches. All the
differences
 *  are found in the DrawingArea class.
 */
public class DrawOnComponent
{
public static void main(String[] args)
{
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}

private static void createAndShowGUI()
{
    DrawingArea drawingArea = new DrawingArea();
    ButtonPanel buttonPanel = new ButtonPanel( drawingArea );

    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame("Draw On Component");
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame.getContentPane().add(drawingArea);
    frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
    frame.setSize(400, 400);
    frame.setLocationRelativeTo( null );
    frame.setVisible(true);
}

static class ButtonPanel extends JPanel implements ActionListener
{
    private DrawingArea drawingArea;

    public ButtonPanel(DrawingArea drawingArea)
    {
        this.drawingArea = drawingArea;

        add( createButton(" ", Color.BLACK) );
        add( createButton(" ", Color.RED) );
        add( createButton(" ", Color.GREEN) );
        add( createButton(" ", Color.BLUE) );
        add( createButton(" ", Color.ORANGE) );
        add( createButton(" ", Color.YELLOW) );
        add( createButton("Clear Drawing", null) );
    }

    private JButton createButton(String text, Color background)
    {
        JButton button = new JButton( text );
        button.setBackground( background );
        button.addActionListener( this );

        return button;
    }

    public void actionPerformed(ActionEvent e)
    {
        JButton button = (JButton)e.getSource();

        if ("Clear Drawing".equals(e.getActionCommand()))
            drawingArea.clear();
        else
            drawingArea.setForeground( button.getBackground() );
    }
}

static class DrawingArea extends JPanel
{
    private final static int AREA_SIZE = 400;
    private ArrayList<ColoredRectangle> coloredRectangles = new ArrayList<ColoredRectangle>();
    private Rectangle shape;

    public DrawingArea()
    {
        setBackground(Color.WHITE);

        MyMouseListener ml = new MyMouseListener();
        addMouseListener(ml);
        addMouseMotionListener(ml);
    }

    @Override
    public Dimension getPreferredSize()
    {
        return isPreferredSizeSet() ?
            super.getPreferredSize() : new Dimension(AREA_SIZE, AREA_SIZE);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        //  Custom code to paint all the Rectangles from the List

        Color foreground = g.getColor();

        g.setColor( Color.BLACK );
        g.drawString("Add a rectangle by doing mouse press, drag and release!", 40, 15);

        for (DrawingArea.ColoredRectangle cr : coloredRectangles)
        {
            g.setColor( cr.getForeground() );
            Rectangle r = cr.getRectangle();
            g.drawRect(r.x, r.y, r.width, r.height);
        }

        //  Paint the Rectangle as the mouse is being dragged

        if (shape != null)
        {
            Graphics2D g2d = (Graphics2D)g;
            g2d.setColor( foreground );
            g2d.draw( shape );
        }
    }

    public void addRectangle(Rectangle rectangle, Color color)
    {
        //  Add the Rectangle to the List so it can be repainted

        ColoredRectangle cr = new ColoredRectangle(color, rectangle);
        coloredRectangles.add( cr );
        repaint();
    }

    public void clear()
    {
        coloredRectangles.clear();
        repaint();
    }

    class MyMouseListener extends MouseInputAdapter
    {
        private Point startPoint;

        public void mousePressed(MouseEvent e)
        {
            startPoint = e.getPoint();
            shape = new Rectangle();
        }

        public void mouseDragged(MouseEvent e)
        {
            int x = Math.min(startPoint.x, e.getX());
            int y = Math.min(startPoint.y, e.getY());
            int width = Math.abs(startPoint.x - e.getX());
            int height = Math.abs(startPoint.y - e.getY());

            shape.setBounds(x, y, width, height);
            repaint();
        }

        public void mouseReleased(MouseEvent e)
        {
            if (shape.width != 0 || shape.height != 0)
            {
                addRectangle(shape, e.getComponent().getForeground());
            }

            shape = null;
        }
    }

    class ColoredRectangle
    {
        private Color foreground;
        private Rectangle rectangle;

        public ColoredRectangle(Color foreground, Rectangle rectangle)
        {
            this.foreground = foreground;
            this.rectangle = rectangle;
        }

        public Color getForeground()
        {
            return foreground;
        }

        public void setForeground(Color foreground)
        {
            this.foreground = foreground;
        }

        public Rectangle getRectangle()
        {
            return rectangle;
        }
    }
}
}
</code>```

I know that I must override the 'paint' method  and as a hard-coded exercise I have included the following in my code:

```<code>public void paint(Graphics g, String color)
{
    if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.BLUE);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.GREEN);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.RED);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.GREEN);
        g.fillRect(50,90,100,50);
    }
    else if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.BLUE);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.RED);
        g.fillOval(50, 180, 55, 55);
    }
}
}
</code>```

I am unsure how to record coordinates of a user's button click and to then pass those coordinates into the constructor of the desired shape.

答:
The following is a suggested implementation, also incorporating the good guidance you got from Frakcool:

```<code>import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class GUI
{
    private final ButtonGroup colorGroup; //group  buttons
    private final ButtonGroup shapeGroup; //so only one can be selected at any given time
    private final Map<String, Color> colors; //map colors to it names.
    private Color color; // color for painting
    private Shape shape; //shape to paint
    private JFrame frame;
    private JPanel buttonsPane;
    private JTextArea textArea;

    private static final int ROWS = 2, COLS = 3;
    private static final String[] BUTTONS_LABELS = {"Rectangle", "Circle", "Exit"};

    public GUI()
    {
        shapeGroup = new ButtonGroup(); colorGroup = new ButtonGroup();
        colors = new HashMap<>();
        colors.put("Red", Color.RED); colors.put("Green", Color.GREEN); colors.put("Blue", Color.BLUE);
    }

    private void createAndShowGUI(String title) {
        frame = new JFrame(title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //use a GridLayout for the buttons pane
        buttonsPane = new JPanel();
        buttonsPane.setLayout(new GridLayout(ROWS, COLS));
        frame.getContentPane().add(buttonsPane, BorderLayout.CENTER);//each BorderLayout position can hold ONE component

        for(String colorName : colors.keySet()){
            JToggleButton button = makeButton(colorName);
            buttonsPane.add(button);
            colorGroup.add(button);
            button.addActionListener(changeColorAction());
        }

        for(String text : BUTTONS_LABELS){
            JToggleButton button = makeButton(text);
            buttonsPane.add(button);
            shapeGroup.add(button);
            button.addActionListener(changeShapeAction());
        }

        setDefaults();

        frame.getContentPane().add(new Draw(), BorderLayout.WEST);
        textArea = new JTextArea(0,20);
        frame.getContentPane().add(textArea, BorderLayout.EAST);

        frame.pack();
        frame.setVisible(true);
    }

    private JToggleButton makeButton(String text) {
        JToggleButton b = new JToggleButton(text); //use toggle buttons
        b.setHorizontalAlignment(SwingConstants.LEFT);
        b.setPreferredSize(new Dimension(100, 80)); //set preferred and let Layout manager do its work
        return b;
    }

    private ActionListener changeColorAction() {
        return e->{
            color = colors.get(((JToggleButton)e.getSource()).getText());
            frame.repaint();
        };
    }

    private ActionListener changeShapeAction() {
        return e->{
            switch (((JToggleButton)e.getSource()).getText()){

                case "Circle":
                    shape = Shape.CIRCLE;
                    break;
                case "Rectangle":
                    shape = Shape.RECTANGLE;
                    break;
                default: System.exit(0);
            }

            frame.repaint();
        };
    }

    private void setDefaults() {
        colorGroup.getElements().nextElement().setSelected(true);
        color = colors.get(colorGroup.getElements().nextElement().getText());
        shapeGroup.getElements().nextElement().setSelected(true);
        shape = Shape.RECTANGLE;
    }

      public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> new GUI().createAndShowGUI("My Gui"));
        }

    class Draw extends JPanel{

        private final Point[] points; // an array to hold clicked points
        private int mouseClicks = 0;
        private static final int POINT_SIZE = 2;

        Draw(){
            setLayout(new BorderLayout());
            setBackground(Color.WHITE);
            setPreferredSize(new Dimension(200, 200));

            JLabel help = new JLabel("Click 2 points to draw");
            help.setHorizontalAlignment(SwingConstants.CENTER);
            add(help, BorderLayout.PAGE_START);

            JLabel timeLabel = new JLabel("current time here");
            timeLabel.setHorizontalAlignment(SwingConstants.LEFT);
            add(timeLabel, BorderLayout.PAGE_END);

            points = new Point[2];
            addMouseListener(new MouseAdapter(){
                @Override
                public void mouseClicked(MouseEvent e) {
                    addPoint(e.getX(), +e.getY() );
                }
            });
        }

        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.setColor(color);
            for(Point point : points)
                if(point != null){
                    g.drawOval(point.x, point.y, POINT_SIZE, POINT_SIZE);
                }

            drawShape((Graphics2D)g);
        }

        private void addPoint(int x, int y) {
            if(mouseClicks ==2){
                mouseClicks = 0;
                points[1] = null;
            }

            points[mouseClicks++] = new Point(x, y);
            repaint();
        }

        private void drawShape(Graphics2D g2d) {

            if(points[0] == null ||  points[1] == null) return;
            if(shape == Shape.RECTANGLE) {
                drawRectangle(g2d);
            }else{
                drawCircle(g2d);
            }
        }

        private void drawRectangle(Graphics2D g2D) {

            int minX = Math.min(points[0].x, points[1].x);
            int minY = Math.min(points[0].y, points[1].y);
            int maxX = Math.max(points[0].x, points[1].x);
            int maxY = Math.max(points[0].y, points[1].y);
            int width  = maxX - minX;
            int height = maxY - minY;
            Rectangle2D.Double rectangle = new Rectangle2D.Double(minX, minY, width, height);
            g2D.draw(rectangle);
        }

        private void drawCircle(Graphics2D g2D) {

            int minX = Math.min(points[0].x, points[1].x);
            int minY = Math.min(points[0].y, points[1].y);
            int maxX = Math.max(points[0].x, points[1].x);
            int maxY = Math.max(points[0].y, points[1].y);
            double dx  = maxX - minX;
            double dy = maxY - minY;
            double radius =  Math.sqrt(dx*dx + dy*dy)/2;
            double centerX = minX + dx/2;
            double centerY = minY + dy/2;

            g2D.draw(new Ellipse2D.Double(centerX - radius , centerY - radius, 2* radius, 2* radius));
        }
    }

    enum Shape {
        RECTANGLE, CIRCLE
    }
}
</code>```

Body:
As part of a larger project I'm trying to create a basic UI that will allow a user to click a JButton to select a desired color and then allow that user to click another JButton to designate a shape to be displayed, filled in according to the previously selected color.  I understand that I must make use of action events.

Please note I am referencing this similar question:

GUI Application that allows the user to choose the shape and color of a drawing

My code thus far is:

import java.util.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;

public class GUI extends JFrame implements ActionListener, WindowListener
{
private final JButton circleButton, rectangleButton, redButton;
private final JButton greenButton, blueButton, exitButton;
private final JTextArea textArea;
private final JLabel label1;
private final JPanel colorPane;

private String shapeColor = "black";
private String actualShape = "rectangle";

private static final int ROWS = 2, COLS = 3;

public GUI (String title)
{
    super(title);
    //setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    colorPane = new JPanel();

    label1 = new JLabel("current date here");
    label1.setVerticalAlignment(SwingConstants.BOTTOM);
    label1.setHorizontalAlignment(SwingConstants.LEFT);
    label1.setPreferredSize(new Dimension(200,0));
    getContentPane().add(label1, BorderLayout.WEST);

    colorPane.setLayout(new GridLayout(ROWS,COLS));
    getContentPane().add(colorPane, BorderLayout.CENTER);

    redButton = makeButton("Red");
    colorPane.add(redButton);
    greenButton = makeButton("Green");
    colorPane.add(greenButton);
    blueButton = makeButton("Blue");
    colorPane.add(blueButton);
    rectangleButton = makeButton("Rectangle");
    colorPane.add(rectangleButton);
    circleButton = makeButton("Circle");
    colorPane.add(circleButton);
    exitButton = makeButton("Exit");
    colorPane.add(exitButton);

    textArea = new JTextArea(0,20);
    getContentPane().add(textArea, BorderLayout.EAST);

    pack();
}

public void paint(Graphics g, String color)
{
    if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.BLUE);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.GREEN);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.RED);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.GREEN);
        g.fillRect(50,90,100,50);
    }
    else if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.BLUE);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.RED);
        g.fillOval(50, 180, 55, 55);
    }
}

//method designed to create new JButtons while avoiding code duplication
private JButton makeButton(String text)
{
    JButton b = new JButton(text);
    b.setHorizontalAlignment(SwingConstants.LEFT);
    b.addActionListener(this);
    b.setPreferredSize(new Dimension(125,55));

    return b;
}

@Override
public void windowOpened(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowClosing(WindowEvent e)
{
    System.exit(0);

}

@Override
public void windowClosed(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowIconified(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowDeiconified(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowActivated(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void windowDeactivated(WindowEvent e) {
    // TODO Auto-generated method stub

}

@Override
public void actionPerformed(ActionEvent e)
{
    System.out.println( ( (JButton)e.getSource() ).getText() + " button pressed ");

    if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Red")) )
    {
        setShapeColor("Red");
        System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
        //paint(this.getGraphics());
    }
    else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Blue")) )
    {
        setShapeColor("Blue");
        System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
        //paint(this.getGraphics());
    }

    else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Green")) )
    {
        setShapeColor("Green");
        System.out.println("selected color is: " + shapeColor + " selected shape is: " + actualShape);
        //paint(this.getGraphics());
    }

    if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Rectangle")) )
    {
        setActualShape("rectangle");
        System.out.println("selected shape is: " + actualShape + " selected color is: " + shapeColor);
        paint(this.getGraphics(), shapeColor);

    }

    else if ( ( ((JButton) e.getSource()).getText().equalsIgnoreCase("Circle")) )
    {
        setActualShape("circle");
        System.out.println("selected shape is: " + actualShape + " selected color is: " + shapeColor);
        paint(this.getGraphics(), shapeColor);
    }

}

public String getShapeColor() {
    return shapeColor;
}

public void setShapeColor(String shapeColor) {
    this.shapeColor = shapeColor;
}

public String getActualShape() {
    return actualShape;
}

public void setActualShape(String actualShape) {
    this.actualShape = actualShape;
}

public static void main(String[] args)
{
    new GUI("My Gui").setVisible(true);
}

}

What I've thus far achieved is an output that shows both the selected color as well as the selected shape to be rendered in the selected color.

Furthermore, I've been successful in outputting a shape whose position is hard-coded but whose type (either circle or square) and whose color (red, blue or green), is correctly output as a result of the user clicks.

The final phase, upon which I am struggling, is the implementation of the shape's output so that the user's sequence of clicks determines the location and dimensions of the shape output to the screen.

The goal is to achieve the functionality demonstrated here:

https://metrostate.learn.minnstate.edu/content/2020/4560296-20201000539/ICS372%20-%20Assignment%202%20Video.mp4?d2lSessionVal=ARifwbCHriCBrkgxBWpL9g8fL&ou=4560296

I'm relatively certain that the correct solution is similar to the following code:

import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

/**
 *  Note: Normally the ButtonPanel and DrawingArea would not be static
classes.
 *  This was done for the convenience of posting the code in one class and
to
 *  highlight the differences between the two approaches. All the
differences
 *  are found in the DrawingArea class.
 */
public class DrawOnComponent
{
public static void main(String[] args)
{
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}

private static void createAndShowGUI()
{
    DrawingArea drawingArea = new DrawingArea();
    ButtonPanel buttonPanel = new ButtonPanel( drawingArea );

    JFrame.setDefaultLookAndFeelDecorated(true);
    JFrame frame = new JFrame("Draw On Component");
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    frame.getContentPane().add(drawingArea);
    frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH);
    frame.setSize(400, 400);
    frame.setLocationRelativeTo( null );
    frame.setVisible(true);
}

static class ButtonPanel extends JPanel implements ActionListener
{
    private DrawingArea drawingArea;

    public ButtonPanel(DrawingArea drawingArea)
    {
        this.drawingArea = drawingArea;

        add( createButton(" ", Color.BLACK) );
        add( createButton(" ", Color.RED) );
        add( createButton(" ", Color.GREEN) );
        add( createButton(" ", Color.BLUE) );
        add( createButton(" ", Color.ORANGE) );
        add( createButton(" ", Color.YELLOW) );
        add( createButton("Clear Drawing", null) );
    }

    private JButton createButton(String text, Color background)
    {
        JButton button = new JButton( text );
        button.setBackground( background );
        button.addActionListener( this );

        return button;
    }

    public void actionPerformed(ActionEvent e)
    {
        JButton button = (JButton)e.getSource();

        if ("Clear Drawing".equals(e.getActionCommand()))
            drawingArea.clear();
        else
            drawingArea.setForeground( button.getBackground() );
    }
}

static class DrawingArea extends JPanel
{
    private final static int AREA_SIZE = 400;
    private ArrayList<ColoredRectangle> coloredRectangles = new ArrayList<ColoredRectangle>();
    private Rectangle shape;

    public DrawingArea()
    {
        setBackground(Color.WHITE);

        MyMouseListener ml = new MyMouseListener();
        addMouseListener(ml);
        addMouseMotionListener(ml);
    }

    @Override
    public Dimension getPreferredSize()
    {
        return isPreferredSizeSet() ?
            super.getPreferredSize() : new Dimension(AREA_SIZE, AREA_SIZE);
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        //  Custom code to paint all the Rectangles from the List

        Color foreground = g.getColor();

        g.setColor( Color.BLACK );
        g.drawString("Add a rectangle by doing mouse press, drag and release!", 40, 15);

        for (DrawingArea.ColoredRectangle cr : coloredRectangles)
        {
            g.setColor( cr.getForeground() );
            Rectangle r = cr.getRectangle();
            g.drawRect(r.x, r.y, r.width, r.height);
        }

        //  Paint the Rectangle as the mouse is being dragged

        if (shape != null)
        {
            Graphics2D g2d = (Graphics2D)g;
            g2d.setColor( foreground );
            g2d.draw( shape );
        }
    }

    public void addRectangle(Rectangle rectangle, Color color)
    {
        //  Add the Rectangle to the List so it can be repainted

        ColoredRectangle cr = new ColoredRectangle(color, rectangle);
        coloredRectangles.add( cr );
        repaint();
    }

    public void clear()
    {
        coloredRectangles.clear();
        repaint();
    }

    class MyMouseListener extends MouseInputAdapter
    {
        private Point startPoint;

        public void mousePressed(MouseEvent e)
        {
            startPoint = e.getPoint();
            shape = new Rectangle();
        }

        public void mouseDragged(MouseEvent e)
        {
            int x = Math.min(startPoint.x, e.getX());
            int y = Math.min(startPoint.y, e.getY());
            int width = Math.abs(startPoint.x - e.getX());
            int height = Math.abs(startPoint.y - e.getY());

            shape.setBounds(x, y, width, height);
            repaint();
        }

        public void mouseReleased(MouseEvent e)
        {
            if (shape.width != 0 || shape.height != 0)
            {
                addRectangle(shape, e.getComponent().getForeground());
            }

            shape = null;
        }
    }

    class ColoredRectangle
    {
        private Color foreground;
        private Rectangle rectangle;

        public ColoredRectangle(Color foreground, Rectangle rectangle)
        {
            this.foreground = foreground;
            this.rectangle = rectangle;
        }

        public Color getForeground()
        {
            return foreground;
        }

        public void setForeground(Color foreground)
        {
            this.foreground = foreground;
        }

        public Rectangle getRectangle()
        {
            return rectangle;
        }
    }
}
}

I know that I must override the 'paint' method  and as a hard-coded exercise I have included the following in my code:

public void paint(Graphics g, String color)
{
    if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.BLUE);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.GREEN);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.RED);
        g.fillRect(50, 90, 100, 50);
    }
    else if (shapeColor.equalsIgnoreCase("green") && actualShape.equalsIgnoreCase("rectangle"))
    {
        g.setColor(Color.GREEN);
        g.fillRect(50,90,100,50);
    }
    else if (shapeColor.equalsIgnoreCase("blue") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.BLUE);
        g.fillOval(50, 180, 55, 55);
    }
    else if (shapeColor.equalsIgnoreCase("red") && actualShape.equalsIgnoreCase("circle"))
    {
        g.setColor(Color.RED);
        g.fillOval(50, 180, 55, 55);
    }
}
}

I am unsure how to record coordinates of a user's button click and to then pass those coordinates into the constructor of the desired shape.

Body:
The following is a suggested implementation, also incorporating the good guidance you got from Frakcool:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.HashMap;
import java.util.Map;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class GUI
{
    private final ButtonGroup colorGroup; //group  buttons
    private final ButtonGroup shapeGroup; //so only one can be selected at any given time
    private final Map<String, Color> colors; //map colors to it names.
    private Color color; // color for painting
    private Shape shape; //shape to paint
    private JFrame frame;
    private JPanel buttonsPane;
    private JTextArea textArea;

    private static final int ROWS = 2, COLS = 3;
    private static final String[] BUTTONS_LABELS = {"Rectangle", "Circle", "Exit"};

    public GUI()
    {
        shapeGroup = new ButtonGroup(); colorGroup = new ButtonGroup();
        colors = new HashMap<>();
        colors.put("Red", Color.RED); colors.put("Green", Color.GREEN); colors.put("Blue", Color.BLUE);
    }

    private void createAndShowGUI(String title) {
        frame = new JFrame(title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //use a GridLayout for the buttons pane
        buttonsPane = new JPanel();
        buttonsPane.setLayout(new GridLayout(ROWS, COLS));
        frame.getContentPane().add(buttonsPane, BorderLayout.CENTER);//each BorderLayout position can hold ONE component

        for(String colorName : colors.keySet()){
            JToggleButton button = makeButton(colorName);
            buttonsPane.add(button);
            colorGroup.add(button);
            button.addActionListener(changeColorAction());
        }

        for(String text : BUTTONS_LABELS){
            JToggleButton button = makeButton(text);
            buttonsPane.add(button);
            shapeGroup.add(button);
            button.addActionListener(changeShapeAction());
        }

        setDefaults();

        frame.getContentPane().add(new Draw(), BorderLayout.WEST);
        textArea = new JTextArea(0,20);
        frame.getContentPane().add(textArea, BorderLayout.EAST);

        frame.pack();
        frame.setVisible(true);
    }

    private JToggleButton makeButton(String text) {
        JToggleButton b = new JToggleButton(text); //use toggle buttons
        b.setHorizontalAlignment(SwingConstants.LEFT);
        b.setPreferredSize(new Dimension(100, 80)); //set preferred and let Layout manager do its work
        return b;
    }

    private ActionListener changeColorAction() {
        return e->{
            color = colors.get(((JToggleButton)e.getSource()).getText());
            frame.repaint();
        };
    }

    private ActionListener changeShapeAction() {
        return e->{
            switch (((JToggleButton)e.getSource()).getText()){

                case "Circle":
                    shape = Shape.CIRCLE;
                    break;
                case "Rectangle":
                    shape = Shape.RECTANGLE;
                    break;
                default: System.exit(0);
            }

            frame.repaint();
        };
    }

    private void setDefaults() {
        colorGroup.getElements().nextElement().setSelected(true);
        color = colors.get(colorGroup.getElements().nextElement().getText());
        shapeGroup.getElements().nextElement().setSelected(true);
        shape = Shape.RECTANGLE;
    }

      public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> new GUI().createAndShowGUI("My Gui"));
        }

    class Draw extends JPanel{

        private final Point[] points; // an array to hold clicked points
        private int mouseClicks = 0;
        private static final int POINT_SIZE = 2;

        Draw(){
            setLayout(new BorderLayout());
            setBackground(Color.WHITE);
            setPreferredSize(new Dimension(200, 200));

            JLabel help = new JLabel("Click 2 points to draw");
            help.setHorizontalAlignment(SwingConstants.CENTER);
            add(help, BorderLayout.PAGE_START);

            JLabel timeLabel = new JLabel("current time here");
            timeLabel.setHorizontalAlignment(SwingConstants.LEFT);
            add(timeLabel, BorderLayout.PAGE_END);

            points = new Point[2];
            addMouseListener(new MouseAdapter(){
                @Override
                public void mouseClicked(MouseEvent e) {
                    addPoint(e.getX(), +e.getY() );
                }
            });
        }

        @Override
        public void paintComponent(Graphics g){
            super.paintComponent(g);
            g.setColor(color);
            for(Point point : points)
                if(point != null){
                    g.drawOval(point.x, point.y, POINT_SIZE, POINT_SIZE);
                }

            drawShape((Graphics2D)g);
        }

        private void addPoint(int x, int y) {
            if(mouseClicks ==2){
                mouseClicks = 0;
                points[1] = null;
            }

            points[mouseClicks++] = new Point(x, y);
            repaint();
        }

        private void drawShape(Graphics2D g2d) {

            if(points[0] == null ||  points[1] == null) return;
            if(shape == Shape.RECTANGLE) {
                drawRectangle(g2d);
            }else{
                drawCircle(g2d);
            }
        }

        private void drawRectangle(Graphics2D g2D) {

            int minX = Math.min(points[0].x, points[1].x);
            int minY = Math.min(points[0].y, points[1].y);
            int maxX = Math.max(points[0].x, points[1].x);
            int maxY = Math.max(points[0].y, points[1].y);
            int width  = maxX - minX;
            int height = maxY - minY;
            Rectangle2D.Double rectangle = new Rectangle2D.Double(minX, minY, width, height);
            g2D.draw(rectangle);
        }

        private void drawCircle(Graphics2D g2D) {

            int minX = Math.min(points[0].x, points[1].x);
            int minY = Math.min(points[0].y, points[1].y);
            int maxX = Math.max(points[0].x, points[1].x);
            int maxY = Math.max(points[0].y, points[1].y);
            double dx  = maxX - minX;
            double dy = maxY - minY;
            double radius =  Math.sqrt(dx*dx + dy*dy)/2;
            double centerX = minX + dx/2;
            double centerY = minY + dy/2;

            g2D.draw(new Ellipse2D.Double(centerX - radius , centerY - radius, 2* radius, 2* radius));
        }
    }

    enum Shape {
        RECTANGLE, CIRCLE
    }
}


答:
Shouldn't you join tables on SIFRA, e.g.

```<code>select p.sifra_rad, s.ime, p.dat_izd
from kpol p join sifrad s on p.sifra_rad = s.sifra_r
where extract (year from p.izd_dat) = 2013
</code>```

Your query joins IME and SIFRA, which seems to be incorrect.

[EDIT, with sample data]

```<code>SQL> with
  2  kpol (sifra_rad, dat_izd) as
  3    (select '7654' , date '2009-01-01' from dual union all
  4     select '00547', date '2013-03-01' from dual union all
  5     select '00214', date '2013-03-01' from dual union all
  6     select '00547', date '2013-04-01' from dual union all
  7     select '00654', date '2013-04-04' from dual
  8    ),
  9  sifrad (sifra_r, ime) as
 10    (select '00214', 'Test123' from dual union all
 11     select '00547', 'Aladin'  from dual union all
 12     select '00654', 'Test'    from dual union all
 13     select '0214' , 'AbBbCc'  from dual
 14    )
 15  select p.sifra_rad,
 16         s.ime,
 17         p.dat_izd
 18  from kpol p join sifrad s on p.sifra_rad = s.sifra_r
 19  where extract (year from p.dat_izd) = 2013
 20  order by p.sifra_rad;

SIFRA IME     DAT_IZD
----- ------- ----------
00214 Test123 01.03.2013
00547 Aladin  01.04.2013
00547 Aladin  01.03.2013
00654 Test    04.04.2013

SQL>
</code>```

Title: After select data from two table using JOIN I get NULL

Body:
I am trying to combine data from one table, and data from another table to get the list of employee.

The situation is following. In one table(t1 ->KPOL) I have columns like

SIFRA_RAD, DAT_IZD, POLICA, MAT_BROJ, MJE_SIG, UL_BROJ, OPSTINA, DAT_IZD

And another table(t2->SIFRAD) I have columns

SIFRA_R, IME, OSTALI_POD, DATUM_UNOSA, DATUM_PROMJENE, RADNIk_UNIO, DATUM_ISTEKA

Here is tabular schema of my data.

KPOL

  -------------------------------------------------Table KPOL------------------------------------------------------------------------------------------------
    SIFRA_RAD    DAT_IZD    POLICA      MAT_BROJ              MJE_SIG       UL_BROJ             OPSTINA              DAT_IZD

1.  "7654"      "1.1.2009"  "Z1A2B"      "06051987215444"       "USA"        "Neka Tamo 21"     "Jerricho"           "1.1.2015"
2   "4581"      "1.2.2007"  "A58547"     "65412398766666"       "DEU"        "Love Sthrase"     "Munich"             "1.2.2012"
3.  "00547"     "1.3.2013"  "65A565"     "44654789621789"       "GR"         "Huston Street"        "London"         "1.3.2012"
4.  "00214"     "1.3.2013"  "789789"     "28736428742313"       "USA"        "Next Street"      "Munchester"         "1.4.2013"
5.  "00547"     "1.4.2013"  "789856"     "74789798564656"       "USA"        "Pro Nano 21"      "Munchester"         "1.5.2013"
6.  "00654"     "4.4.2013"  "657989"     "78965423413213"       "USA"        "iuadsgdkj"        "Hamburg"             "6.3.2013"

-----------------------------------------------------------------------------------------------------------------------------------------------------------

SIFRAD

    -----------------------------------------Table SIFRAD-------------------------------------------------------------------------------------------------------
 SIFRA_R        IME     OSTALI_POD      DATUM_UNOSA   DATUM_PROMJENE    RADNIK_UNIO DATUM_ISTEKA
    00214       Test123     Head of IT      31.12.2012  1.1.2013    333333123   1.5.2019
    00547       Aladin      Economic        8.5.2012    2.3.2013    32111111    31.12.2012
    00654       TestTest    Head of Management  2.2.2013    4.5.2014    11111111    1.1.2016
    0214        AaBbCc      Business        3.2.2014    6.5.2014    66666666    2.9.2019
    --------------------------------------------------------------------------------------------------------------------------------------------------------------

After combining SIFRA_RAD (table KPOL), IME (table SIFRAD), DAT_IZD (table KPOL) it should look like this

SIFRA_RAD     IME        DAT_IZD
------------------------------------
"00654"     "TestTest   "1.4.2013"
"00547"     "Aladin "   "1.5.2013"
"00214"     "AaBbCc"    "4.4.2013"

It should display all employee how release(DAT_IZD) policy in 2013 year

So far what I did is following query:

SELECT P.SIFRA_RAD, S.IME, P.DAT_IZD
FROM AUTO.SIFRAD S
LEFT JOIN AUTO.KPOL P ON S.IME = P.SIFRA_RAD
                      AND EXTRACT(YEAR FROM P.DAT_IZD) = 2013;

But so far I can't get any data in table.

After I use SELECT statment for table KPOL  to select SIFRA_RAD and DAT_IZD by using following query I get:

select sifra_rad, dat_izd
from kpol
where extract(year from dat_izd) = '2013'
order by dat_izd asc

I believe the problem comes from my query. Can anyone help me guys to find what is the problem here?

Table KPOL:

SIFRA_RAD   DAT_IZD
----------------------
00654       1.1.2007
00654       1.1.2007
00221       1.1.2007
00698       2.1.2007
00987       3.3.2013
00214       3.4.2013
00698       3.5.2013
etc     etc

Body:
Shouldn't you join tables on SIFRA, e.g.

select p.sifra_rad, s.ime, p.dat_izd
from kpol p join sifrad s on p.sifra_rad = s.sifra_r
where extract (year from p.izd_dat) = 2013

Your query joins IME and SIFRA, which seems to be incorrect.

[EDIT, with sample data]

SQL> with
  2  kpol (sifra_rad, dat_izd) as
  3    (select '7654' , date '2009-01-01' from dual union all
  4     select '00547', date '2013-03-01' from dual union all
  5     select '00214', date '2013-03-01' from dual union all
  6     select '00547', date '2013-04-01' from dual union all
  7     select '00654', date '2013-04-04' from dual
  8    ),
  9  sifrad (sifra_r, ime) as
 10    (select '00214', 'Test123' from dual union all
 11     select '00547', 'Aladin'  from dual union all
 12     select '00654', 'Test'    from dual union all
 13     select '0214' , 'AbBbCc'  from dual
 14    )
 15  select p.sifra_rad,
 16         s.ime,
 17         p.dat_izd
 18  from kpol p join sifrad s on p.sifra_rad = s.sifra_r
 19  where extract (year from p.dat_izd) = 2013
 20  order by p.sifra_rad;

SIFRA IME     DAT_IZD
----- ------- ----------
00214 Test123 01.03.2013
00547 Aladin  01.04.2013
00547 Aladin  01.03.2013
00654 Test    04.04.2013

SQL>


问:
Limitation for semantic drop-down multiple selection
I am trying to have a Semantic UI dropdown menu which allows additions but I don't want user to have more than 4 selection.

When user added 4 items to his selection, 4 labels will be added, now he shouldn't be able to add more labels to his selection.

How can I achieve that?

答:
You can use the select2.js for the multiple select drop down with limitation.

https://select2.org/getting-started/basic-usage

For more appropriate solution please share your code here.