In Java 1.7 or later, the standard way to do this is as follows:
import java.util.concurrent.ThreadLocalRandom;
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = ThreadLocalRandom.current().nextInt(min, max + 1);
See the relevant JavaDoc. This approach has the advantage of not needing to explicitly initialize a java.util.Random instance, which can be a source of confusion and error if used inappropriately.
However, conversely there is no way to explicitly set the seed so it can be difficult to reproduce results in situations where that is useful such as testing or saving game states or similar. In those situations, the pre-Java 1.7 technique shown below can be used.
Before Java 1.7, the standard way to do this is as follows:
import java.util.Random;
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
* <code>Integer.MAX_VALUE - 1</code>.
*
* @param min Minimum value
* @param max Maximum value. Must be greater than min.
* @return Integer between min and max, inclusive.
* @see java.util.Random#nextInt(int)
*/
public static int randInt(int min, int max) {
// NOTE: This will (intentionally) not run as written so that folks
// copy-pasting have to think about how to initialize their
// Random instance. Initialization of the Random instance is outside
// the main scope of the question, but some decent options are to have
// a field that is initialized once and then re-used as needed or to
// use ThreadLocalRandom (if using at least Java 1.7).
//
// In particular, do NOT do 'Random rand = new Random()' here or you
// will get not very good / not very random results.
Random rand;
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
See the relevant JavaDoc. In practice, the java.util.Random class is often preferable to java.lang.Math.random().
In particular, there is no need to reinvent the random integer generation wheel when there is a straightforward API within the standard library to accomplish the task.
You can manually create the JFreeChart object instead of using ChartFactory. First generate the datasets and Plot, setting each dataset to an index. Then you can customize the Plot with the necessary Axis and Renderer. Here's an example for doing so with dummy data that has two datasets, each with different magnitude y-values:
//create the series - add some dummy data
XYSeries series1 = new XYSeries("series1");
XYSeries series2 = new XYSeries("series2");
series1.add(1000, 1000);
series1.add(1150, 1150);
series1.add(1250, 1250);
series2.add(1000, 111250);
series2.add(1150, 211250);
series2.add(1250, 311250);
//create the datasets
XYSeriesCollection dataset1 = new XYSeriesCollection();
XYSeriesCollection dataset2 = new XYSeriesCollection();
dataset1.addSeries(series1);
dataset2.addSeries(series2);
//construct the plot
XYPlot plot = new XYPlot();
plot.setDataset(0, dataset1);
plot.setDataset(1, dataset2);
//customize the plot with renderers and axis
plot.setRenderer(0, new XYSplineRenderer());//use default fill paint for first series
XYSplineRenderer splinerenderer = new XYSplineRenderer();
splinerenderer.setSeriesFillPaint(0, Color.BLUE);
plot.setRenderer(1, splinerenderer);
plot.setRangeAxis(0, new NumberAxis("Series 1"));
plot.setRangeAxis(1, new NumberAxis("Series 2"));
plot.setDomainAxis(new NumberAxis("X Axis"));
//Map the data to the appropriate axis
plot.mapDatasetToRangeAxis(0, 0);
plot.mapDatasetToRangeAxis(1, 1);
//generate the chart
JFreeChart chart = new JFreeChart("MyPlot", getFont(), plot, true);
chart.setBackgroundPaint(Color.WHITE);
JPanel chartPanel = new ChartPanel(chart);
Best Answer
This all seems unnecessarily complicated: axis ranging and notification should be automatic. In this example, the range changes as outliers accumulate, because
add()
"sends aSeriesChangeEvent
to all registered listeners." In this example, the range is fixed, but the same notification happens.As we can't guess how your program fails in this regard, it may help to provide an sscce that exhibits the problem(s) you describe.