Search code examples
javaandroidteechart

TChart crashes when toggling legend visibility?


When I switch between different TChart series, I get an exception if legend visibility is toggled between the runs. E.g.

  1. Bar chart is displayed. Legend visible.
  2. Pie chart is displayed. Legend invisible.
  3. Bar chart is displayed. Legend visible.
  4. Crash!

This is the line that causes the uncaught exception when the control is repainted:

chart.getLegend().setVisible(true);

Between each run I do the following:

chart.setAutoRepaint(false);
chart.removeAllSeries();
// Build chart...
chart.setAutoRepaint(true);
chart.refreshControl();

TChart experts out there, how can I avoid this crash?


Solution

  • This is not crashing for me. I can switch from Bar to Pie several times without problems.

    package com.steema.test;
    
    import android.app.Activity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.AdapterView.OnItemSelectedListener;
    import android.widget.ArrayAdapter;
    import android.widget.LinearLayout;
    import android.widget.Spinner;
    
    import com.steema.teechart.TChart;
    import com.steema.teechart.styles.Bar;
    import com.steema.teechart.styles.Pie;
    import com.steema.teechart.themes.ThemesList;
    
    public class AndroidTestActivity extends Activity implements OnItemSelectedListener{
    
        private TChart tChart1;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            LinearLayout group = (LinearLayout) findViewById(R.id.linearLayoutTchart);
    
            tChart1 = new TChart(this);
            group.addView(tChart1);
            ThemesList.applyTheme(tChart1.getChart(), 1);
    
            Spinner spinner = (Spinner) findViewById(R.id.series_spinner);
            ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.series_array, android.R.layout.simple_spinner_item);
            adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
            spinner.setAdapter(adapter);
            spinner.setOnItemSelectedListener(this);
        }
    
        @Override
        public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
            tChart1.setAutoRepaint(false);
            tChart1.removeAllSeries();
            switch (arg2) {
            case 0:
                Bar bar1 = new Bar(tChart1.getChart());
                bar1.fillSampleValues();
                tChart1.getLegend().setVisible(true);
                break;
            case 1:
                Pie pie1 = new Pie(tChart1.getChart());
                pie1.fillSampleValues();
                tChart1.getLegend().setVisible(false);
                break;
            }
            tChart1.setAutoRepaint(true);
            tChart1.refreshControl();
        }
    
        @Override
        public void onNothingSelected(AdapterView<?> arg0) {
    
        }
    }
    

    Here it is my main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
        <TextView  
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content" 
            android:text="@string/hello"/>
        <Spinner android:id="@+id/series_spinner"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
        <LinearLayout android:id="@+id/linearLayoutTchart" 
            android:layout_width="fill_parent" 
            android:layout_height="wrap_content"/>
    </LinearLayout>
    

    And here my strings.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <string name="hello">TeeChartJava for Android testing application!</string>
        <string name="app_name">AndroidTest</string>
        <string-array name="series_array">
            <item>Bar</item>
            <item>Pie</item>
        </string-array>
    </resources>
    

    UPDATE 1: If I add tChart1.getLegend().setSeries(tChart1.getSeries(0)); above int he case 1:

        case 1:
            Pie pie1 = new Pie(tChart1.getChart());
            pie1.fillSampleValues();
            tChart1.getLegend().setSeries(tChart1.getSeries(0));
            tChart1.getLegend().setVisible(false);
            break;
    

    Then I get an error message when selecting back the Bar series. This is because we have set the legend to use a Pie series (the fisrt time we select the Pie), we have remove that Pie series when we select the Bar, but the legend still references the removed Pie series. Please, check you have a valid series set to the legend. Ie:

        case 0:
            Bar bar1 = new Bar(tChart1.getChart());
            bar1.fillSampleValues();
            tChart1.getLegend().setSeries(tChart1.getSeries(0));
            tChart1.getLegend().setVisible(true);
            break;
        case 1:
            Pie pie1 = new Pie(tChart1.getChart());
            pie1.fillSampleValues();
            tChart1.getLegend().setSeries(tChart1.getSeries(0));
            tChart1.getLegend().setVisible(false);
            break;
    

    The next version will set getLegend().setSeries(null) in removeAllSeries() after clearing the series list.