JFreeChart not appearing on JPanel - may be something to do with my code's logic

孤者浪人 提交于 2020-01-02 05:19:06

问题


This question relates to a similar question I posted on here a few days ago...

Here is the interface which will show where I am wanting the chart to appear:

I am wanting to display the chart on the large JPanel on the right hand side. What the chart is meant to do is to compare a particular player's stats with their country's average and the overall average (with three bars). The chart (should) know which player to show the comparison by getting the player's name from the textbox (the one with "getPlayerName" already in it. As with my similar question mentioned earlier, I have created a class (this time called PlayerVsCountryVsOverallChart) - which will deal with building the chart for this particular stat.

The code from the "PlayerVsCountryVsOverallChart" class is quite similar, but I think there is some logic in there that is preventing the chart from showing (or even being made). Since my logic is still developing (with stuff to do with JFreeCharts), I would appreciate it very much if someone can look into this for me.

Here is the code for the PlayerVsCountryVsOverallChart class - minus the necessary imports:

/**
 * This class is responsible for displaying the chart for 
 * the "Player vs Country vs Overall" functionality in the 
 * "Single Player" tab.
 * @author attfire1
 */
public class PlayerVsCountryVsOverallChart extends JPanel
{
    private static final long serialVersionUID = 1L;
    private ArrayList<Player> players;
    private StatUtilities stats;
    public String yAxisLabel = "";
    private String chosenPlayer;
    public String[] compareStatsOptions = new String[] { "Average Balls Bowled", "Average of Bowling Averages", "Average Career Length", "Average Economy Rate", "Average Number of Five Wicket Innings", "Average Innings Played", "Average Matches Played", "Average Runs Conceded", "Average Strike Rate", "Average Wickets Taken" };
    ;

    /**
     * This constructor is responsible for producing the stats bar chart in 
     * the "Single Player Stats" tab in AppInterface.
     * @param applicationTitle
     * @param chartTitle
     * @param players The list of players to iterate through
     * @param option The option which determines what statistics to display
     * @param chosenPlayer The chosen player's name
     */
    public PlayerVsCountryVsOverallChart(String applicationTitle, String chartTitle, ArrayList<Player> players, int option, String chosenPlayer) {
        //super(applicationTitle);

        this.players = players;
        this.chosenPlayer = chosenPlayer;
        stats = new StatUtilities();

        final CategoryDataset dataset = createDataset(option, chosenPlayer);

        // based on the dataset we create the chart
        final JFreeChart chart = createChart(dataset, applicationTitle);

        // we put the chart into a panel
        final ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setPreferredSize(new Dimension(500, 270));

        // Don't forget me...
        setLayout(new BorderLayout());
        add(chartPanel); 
    }

    /**
     * This method returns the nth occurrence of a 
     * character in a given string.
     * 
     * Sourced from https://stackoverflow.com/questions/3976616/how-to-find-nth-occurrence-of-character-in-a-string.
     * @param str The string to get the index of a character from.
     * @param c The character to get the index of.
     * @param n What occurrence of character to retrieve.
     * @return The nth occurrence of a character.
     */
    public static int nthOccurrence(String str, char c, int n) {
        int pos = str.indexOf(c, 0);
        while (n-- > 0 && pos != -1)
            pos = str.indexOf(c, pos+1);
        return pos;
    }



/** * Creates a sample dataset */

    private  CategoryDataset createDataset(int graphDisplayOption, String playerChosen) {

        // row keys... "series"
        final String player = "Player";
        final String country = "Country";
        final String overall = "Overall";



        ArrayList<String> countries = new ArrayList<String>();
        for (Player p : players) {
            countries.add(p.getCountryName());
        }

        //these are also the "column keys"
        Set<String> countryNames = new HashSet<String>(countries);

        final DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        /*
         * The below code block uses a switch statement to determine
         * which type of stats to display in the graph (country by country).
         * 
         * Options for the switch statement are as follows:
         * 
         * 1 = Average Balls Bowled
         * 2 = Average of Bowling Averages
         * 3 = Average Career Lengths
         * 4 = Average Economy Rates
         * 5 = Average Number of 5 Wicket Innings
         * 6 = Average Innings Played
         * 7 = Average Matches Played
         * 8 = Average Runs Conceded
         * 9 = Average Strike Rates
         * 10 = Average WicketsTaken
         */
        for(int i = 0; i < players.size(); i++)
        {
            //if the player's name in iteration i equals the chosen player's name
            if(players.get(i).getPlayerName().equals(playerChosen))
            {
            switch(graphDisplayOption)
                {
                    case 1:
                        yAxisLabel = compareStatsOptions[0];
                        dataset.addValue(players.get(i).getBallsBowled(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveBallsBowled(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveBallsBowled(players), overall, players.get(i).getPlayerName());
                        break;
                    case 2:
                        yAxisLabel = compareStatsOptions[1];
                        dataset.addValue(players.get(i).getBowlingAverage(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveBowlingAverage(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveBowlingAverage(players), overall, players.get(i).getPlayerName());
                        break;
                    case 3:
                        yAxisLabel = compareStatsOptions[2];
                        dataset.addValue(players.get(i).calcCareerSpan(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveCareerLength(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveCareerLength(players), overall, players.get(i).getPlayerName());
                        break;
                    case 4:
                        yAxisLabel = compareStatsOptions[3];
                        dataset.addValue(players.get(i).getEconomyRate(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveEconRate(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveEconRate(players), overall, players.get(i).getPlayerName());
                        break;
                    case 5:
                        yAxisLabel = compareStatsOptions[4];
                        dataset.addValue(players.get(i).getFiveWicketsInnings(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveFiveWicketsInns(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveFiveWicketsInns(players), overall, players.get(i).getPlayerName());
                        break;
                    case 6:
                        yAxisLabel = compareStatsOptions[5];
                        dataset.addValue(players.get(i).getInningsPlayed(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveInningsPerCountry(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveInningsPerPlayer(players), overall, players.get(i).getPlayerName());
                        break;
                    case 7:
                        yAxisLabel = compareStatsOptions[6];
                        dataset.addValue(players.get(i).getMatchesPlayed(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveMatchesPerPlayer(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveMatchesPerPlayer(players), overall, players.get(i).getPlayerName());
                        break;
                    case 8:
                        yAxisLabel = compareStatsOptions[7];
                        dataset.addValue(players.get(i).getRunsConceded(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveRunsConceded(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveRunsConceded(players), overall, players.get(i).getPlayerName());
                        break;
                    case 9:
                        yAxisLabel = compareStatsOptions[8];
                        dataset.addValue(players.get(i).getStrikeRate(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveStrikeRate(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveStrikeRate(players), overall, players.get(i).getPlayerName());
                        break;
                    case 10:
                        yAxisLabel = compareStatsOptions[9];
                        dataset.addValue(players.get(i).getWicketsTaken(), player, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveWickets(players, players.get(i).getCountryName()), country, players.get(i).getPlayerName());
                        dataset.addValue(stats.aveWickets(players), overall, players.get(i).getPlayerName());
                        break;
                }


            }
        }
        return dataset;

    }


/** * Creates a chart */

    private JFreeChart createChart(CategoryDataset dataset, String title) {

        // create the chart...
        final JFreeChart chart = ChartFactory.createBarChart(
            title,         // chart title
            "Countries",               // domain axis label
            yAxisLabel,                  // range axis label
            dataset,                  // data
            PlotOrientation.VERTICAL, // orientation
            true,                     // include legend
            true,                     // tooltips?
            false                     // URLs?
        );

        // NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...

        // set the background color for the chart...
        chart.setBackgroundPaint(Color.white);

        // get a reference to the plot for further customisation...
        final CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setRangeGridlinePaint(Color.white);

        // set the range axis to display integers only...
        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        // disable bar outlines...
        final BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(false);

        // set up gradient paints for series...
        final GradientPaint gp0 = new GradientPaint(
            0.0f, 0.0f, Color.blue, 
            0.0f, 0.0f, Color.lightGray
        );
        final GradientPaint gp1 = new GradientPaint(
            0.0f, 0.0f, Color.green, 
            0.0f, 0.0f, Color.lightGray
        );
        final GradientPaint gp2 = new GradientPaint(
            0.0f, 0.0f, Color.red, 
            0.0f, 0.0f, Color.lightGray
        );
        renderer.setSeriesPaint(0, gp0);

        final CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(
            CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0)
        );
        // OPTIONAL CUSTOMISATION COMPLETED.

        return chart;

    }
}

I wasn't sure what to post for an SSCCE from this class - I have a feeling the problem may lie in the switch-case statement in the "CategoryDataset createDataset" method...

Here is the button listener code for the "Go" button, which should be producing the chart when it is clicked (in conjunction with the option selected in the JComboBox next to it, and the players name from the textbox):

private void confirmGraphBtnActionPerformed(java.awt.event.ActionEvent evt) {                                                
        String selectedOption = String.valueOf(chooseGraphOption.getSelectedItem()).toString();
        int statsOption = options.indexOf(selectedOption);

        processCvPvOchart(statsOption);
    } 

Lastly, here is the code for the processCvPvOchart method:

/**
     * This method processes the chart for the "Player vs Country vs Overall" 
     * player stats, in the "Single Player Stats" tab.
     * @param option The option for which stats to display.
     */
    public void processCvPvOchart(int option)
    {
        //pVcVo = "Player vs Country vs Overall"
        String title = pVcVo.get(option);
        PlayerVsCountryVsOverallChart chart = new PlayerVsCountryVsOverallChart(title, "", players, option + 1, getPlayerName.getText());
        displayGraphPanel.add(chart);
        repaint();

    }

I have committed this code to my project repository on GitHub at https://github.com/rattfieldnz/Java_Projects/tree/master/PCricketStats. Running this and testing it could be beneficial for people that want to help me out. Once I learn more about disecting my code for SSCCE's, I'll include smaller code fragments.


回答1:


The chart itself is largely irrelevant, except that it

  1. Has some preferred size.

  2. Has been added to a Container having a suitable layout.

In the sscce below, a mock player panel and chart panel are added to a GridLayout(1, 0). The ChartPanel is given an arbitrary size by overriding getPreferredSize().

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;

/**
 * @see http://stackoverflow.com/a/16828209/230513
 */
public class Test {

    private static final int N = 128;
    private static final Random random = new Random();

    private void display() {
        JFrame f = new JFrame("Test");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel p = new JPanel(new GridLayout(1, 0));
        p.add(createPlayerPanel());
        p.add(createChartPanel());
        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private ChartPanel createChartPanel() {
        final XYSeries series = new XYSeries("Data");
        for (int i = 0; i < random.nextInt(N) + N / 2; i++) {
            series.add(i, random.nextGaussian());
        }
        XYSeriesCollection dataset = new XYSeriesCollection(series);
        JFreeChart chart = ChartFactory.createXYLineChart("Test", "Domain",
            "Range", dataset, PlotOrientation.VERTICAL, false, false, false);
        return new ChartPanel(chart) {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(N * 2, N * 2);
            }
        };
    }

    private Box createPlayerPanel() {
        Box b = new Box(BoxLayout.Y_AXIS);
        b.setBorder(new EmptyBorder(10, 10, 10, 10));
        for (int i = 0; i < 16; i++) {
            JLabel label = new JLabel();
            label.setAlignmentX(0.5f);
            String s = String.valueOf(label.hashCode());
            label.setText(s + ": " + s);
            b.add(label);
        }
        return b;
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test().display();
            }
        });
    }
}



回答2:


Try to create the graph on its own JPanel then add it to your existing project.

Also look at the jpanel layout and make sure you are using the most appropriate.



来源:https://stackoverflow.com/questions/16826438/jfreechart-not-appearing-on-jpanel-may-be-something-to-do-with-my-codes-logic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!