JFreeChart: How to plot an array of 100000 samples using JFreeChart in a dynamic fashion [duplicate] - jfreechart

I have an array of 100,000 samples all of double type. I want to display or plot this array so that I get a moving chart/ plot (dynamic) instead of displaying it at once. Can anyone help me out. In plot ee[] and y[] is obtained after some processing.
private byte[] FileR(String filename) {
byte[] data = null;
AudioInputStream ais;
try {
File fileIn = new File(filename);
if (fileIn.exists()) {
ais = AudioSystem.getAudioInputStream(fileIn);
data = new byte[ais.available()];
ais.read(data);
}
} catch (UnsupportedAudioFileException | IOException e) {
System.out.println(e.getMessage());
throw new RuntimeException("Could not read " + filename);
}
return data;
}
private byte[] Capture(double t) throws LineUnavailableException {
AudioFormat format = new AudioFormat(48000, 16, 2, true, false);
DataLine.Info info = new DataLine.Info(TargetDataLine.class, format);
line = (TargetDataLine) AudioSystem.getLine(info);
line.open(format);
line.open();
int size = (int) (line.getBufferSize() * t);
byte[] b = new byte[size];
line.start();
line.read(b, 0, size);
return b;
}
private void plot(double[] ee, double[] y) {
XYSeries see = new XYSeries("Filtered");
for (int i = 0; i < ee.length; i++) {
see.add(i, ee[i]);
}
XYSeriesCollection cee = new XYSeriesCollection();
cee.addSeries(see);
XYItemRenderer ree = new StandardXYItemRenderer();
NumberAxis rangeAxisee = new NumberAxis("Filtered");
XYPlot subplot1 = new XYPlot(cee, null, rangeAxisee, ree);
subplot1.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
XYSeries sy = new XYSeries("Noisy");
for (int i = 0; i < y.length; i++) {
sy.add(i, y[i]);
}
XYSeriesCollection cy = new XYSeriesCollection();
cy.addSeries(sy);
XYItemRenderer ry = new StandardXYItemRenderer();
NumberAxis rangeAxisy = new NumberAxis("Noisy");
XYPlot subplot2 = new XYPlot(cy, null, rangeAxisy, ry);
subplot2.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
CombinedDomainXYPlot plot = new CombinedDomainXYPlot(new NumberAxis("Domain"));
plot.setGap(10.0);
plot.add(subplot1);
plot.add(subplot2);
plot.setOrientation(PlotOrientation.VERTICAL);
JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true);
panel = new ChartPanel(chart, true, true, true, false, true);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(750, 500);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
}

You need to have a thread where all this data is coming from. For example from your backend. Then, every time there is a new set of data for the chart you will need to update the chart via the Event Dispatch Thread. If your chart data is coming in regular intervals it is fairly easy (ie. pull), however if it is push (ie. the data is more random), and can get a little more tricky.
Remove all the GUI creation out of the plot method :
JFreeChart chart = new JFreeChart("Adaptive Filter", JFreeChart.DEFAULT_TITLE_FONT, plot, true);
panel = new ChartPanel(chart, true, true, true, false, true);
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(750, 500);
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
This only needs to be called once. The plot method will be called every time new data comes.
Here is a simple approach :
public void startCharting() {
final MySoundCard card = new MySoundCard();
final MyJFreeChart chart = new MyJFreeChart();
Runnable r = new Runnable() {
#Override
public void run() {
while(true) {
int[] i = card.FileR();
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
chart.plot();
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread t = new Thread(r);
t.start();
}
A thread calls your datasource every second and then updates the chart. The updates are invoked in the Event Dispatch Thread.

Related

JFreeChart disable vertical gray areas of XYPlot

The code below plots a graph with unwanted vertical gray areas (stripes) corresponding with alternate domain ticks.
I have tried unsuccessfully to remove them from the graph to obtain a plot with white background.
I have been searching through the methods of XYPlot or NumberAxis (last try was setting to null xyplot.setDomainTickBandPaint(null); and xyplot.setRangeTickBandPaint(null);), but I have not experience enough with JFreeChart to know what method to use.
This is the code for the above graph:
public class MyPlotChart {
private static Color MetalColor = new Color(255, 152, 0);
static double[] yData = new double[] { 49.68, 49.18, 49.78, 49.65, 48.94, 50.02, 50.27};
static String[] labels = new String[] { "2021-10-28", "2021-10-29", "2021-11-01", "2021-11-02", "2021-11-03", "2021-11-04", "2021-11-05"};
public static void plot(String metal, int samples) throws IOException {
XYSeries series = new XYSeries(metal);
int i = 0;
for (i = 0; i < yData.length; i++) {
series.add(i, yData[i]);
}
XYDataset dataset = new XYSeriesCollection(series);
NumberAxis domain = new SymbolAxis(null, labels);
NumberAxis verticalAxis = new NumberAxis(null);
verticalAxis.setAutoRangeIncludesZero(false);
domain.setTickUnit(new NumberTickUnit(1.0));
domain.setMarkerBand(null);
double vericalTickUnit = (series.getMaxY() - series.getMinY()) / 5;
NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
numberFormat.setRoundingMode(RoundingMode.HALF_DOWN);
numberFormat.setMinimumFractionDigits(2);
numberFormat.setMaximumFractionDigits(2);
NumberTickUnit nt = new NumberTickUnit(vericalTickUnit, numberFormat);
verticalAxis.setTickUnit(nt);
verticalAxis.setAutoRange(true);
verticalAxis.setRange(new Range(series.getMinY()-0.1, series.getMaxY()+0.1));
verticalAxis.setTickMarksVisible(true);
verticalAxis.setTickMarkInsideLength(3f);
XYSplineRenderer r = new XYSplineRenderer(10);
r.setSeriesPaint(0, MetalColor);
r.setDefaultShapesVisible(false);
r.setSeriesStroke(0, new BasicStroke(3.0f));
XYPlot xyplot = new XYPlot(dataset, domain, verticalAxis, r);
xyplot.getDomainAxis().setVerticalTickLabels(true);
xyplot.setDomainGridlinesVisible(false);
xyplot.setBackgroundImage(null);
xyplot.setBackgroundPaint(Color.WHITE);
Font font = xyplot.getDomainAxis().getTickLabelFont();
Font fontnew = new Font(font.getName(), Font.BOLD, 14);
xyplot.getDomainAxis().setTickLabelFont(fontnew);
xyplot.getRangeAxis().setTickLabelFont(fontnew);
JFreeChart chart = new JFreeChart(xyplot);
chart.removeLegend();//Remove legend
chart.setBackgroundPaint(Color.WHITE);
String fileName = "myChart"+metal+samples+"TEST.png";
ChartUtils.saveChartAsPNG(new File(fileName), chart, 600, 600);
}
public static void main(String[] args) throws IOException {
MyPlotChart.plot("metal", 7);
}
}
As suggested in the comment, I opted to use DateAxis which do not implement alternating background and also gives more accurate treatment for tick labels when the data is time related.
I have attached the code and the plot obtained:
public class MyPlotChart {
private static Color MetalColor = new Color(255, 152, 0);
static double[] yData = new double[] { 49.68, 49.18, 49.78, 49.65, 48.94, 50.02, 50.27 };
static String[] labels = new String[] { "2021-10-28", "2021-10-29", "2021-11-01", "2021-11-02", "2021-11-03",
"2021-11-04", "2021-11-05" };
public static void plot(String metal, int samples) throws IOException, ParseException {
SimpleDateFormat dateformatyyyy_MM_dd = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat dateformatdd_MM_yyyy = new SimpleDateFormat("dd-MM-yyyy");
XYSeries series = new XYSeries(metal);
for (int i = 0; i < yData.length; i++) {
Date date = dateformatyyyy_MM_dd.parse(labels[i]);
series.add(date.getTime(), yData[i]);
}
//Configure Vertical Axis
NumberAxis verticalAxis = new NumberAxis(null);
NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault());
numberFormat.setRoundingMode(RoundingMode.HALF_DOWN);
numberFormat.setMinimumFractionDigits(2);
numberFormat.setMaximumFractionDigits(2);
double vericalTickUnit = (series.getMaxY() - series.getMinY()) / 7;
NumberTickUnit nt = new NumberTickUnit(vericalTickUnit, numberFormat);
verticalAxis.setTickUnit(nt);
double percentOverRange = 0.05;// 2%
double initalRange = series.getMaxY() - series.getMinY();
double increase = initalRange * percentOverRange;
verticalAxis.setRange(new Range(series.getMinY()-increase, series.getMaxY()+increase));
verticalAxis.setAutoRange(true);
verticalAxis.setAutoRangeIncludesZero(false);
verticalAxis.setTickMarksVisible(true);
verticalAxis.setTickMarkInsideLength(3f);
//Configure Domain Axis
DateAxis domainAxis = new DateAxis(null);
domainAxis.setTickUnit(new DateTickUnit(DateTickUnitType.DAY, 1, dateformatdd_MM_yyyy));
//Configure Renderer
XYSplineRenderer r = new XYSplineRenderer(10);
r.setSeriesPaint(0, MetalColor);
r.setDefaultShapesVisible(false);
r.setSeriesStroke(0, new BasicStroke(3.0f));
XYDataset dataset = new XYSeriesCollection(series);
XYPlot xyplot = new XYPlot(dataset, domainAxis, verticalAxis, r);
xyplot.getDomainAxis().setVerticalTickLabels(true);
xyplot.setDomainGridlinesVisible(false);
xyplot.setBackgroundImage(null);
xyplot.setBackgroundPaint(Color.WHITE);
Font font = xyplot.getDomainAxis().getTickLabelFont();
Font fontnew = new Font(font.getName(), Font.BOLD, 14);
xyplot.getDomainAxis().setTickLabelFont(fontnew);
xyplot.getRangeAxis().setTickLabelFont(fontnew);
JFreeChart chart = new JFreeChart(xyplot);
chart.removeLegend();// Remove legend
chart.setBackgroundPaint(Color.WHITE);
String fileName = "myChart" + metal + samples + "TEST.png";
ChartUtils.saveChartAsPNG(new File(fileName), chart, 600, 600);
}
public static void main(String[] args) throws IOException, ParseException {
MyPlotChart.plot("metal", 7);
}
}

iOS save to storage issue

I've an issue while trying to save an image to the Storage in iOS. Image is downloaded but not saved.
The code is:
Form hi = new Form("Toolbar", new BoxLayout(BoxLayout.Y_AXIS));
TreeModel tm = new TreeModel() {
#Override
public Vector getChildren(Object parent) {
String[] files;
if (parent == null) {
files = FileSystemStorage.getInstance().getRoots();
return new Vector<Object>(Arrays.asList(files));
} else {
try {
files = FileSystemStorage.getInstance().listFiles((String) parent);
} catch (IOException err) {
Log.e(err);
files = new String[0];
}
}
String p = (String) parent;
Vector result = new Vector();
for (String s : files) {
result.add(p + s);
}
return result;
}
#Override
public boolean isLeaf(Object node) {
return !FileSystemStorage.getInstance().isDirectory((String) node);
}
};
Command tree = new Command("Show tree") {
#Override
public void actionPerformed(ActionEvent evt) {
Form treeForm = new Form("Tree", new BorderLayout());
Tree t = new Tree(tm) {
#Override
protected String childToDisplayLabel(Object child) {
String n = (String) child;
int pos = n.lastIndexOf("/");
if (pos < 0) {
return n;
}
return n.substring(pos);
}
};
treeForm.add(BorderLayout.CENTER, t);
Command back = new Command("Back") {
#Override
public void actionPerformed(ActionEvent evt) {
hi.showBack();
}
};
Button backButton = new Button(back);
treeForm.add(BorderLayout.SOUTH, backButton);
treeForm.show();
}
};
hi.getToolbar().addCommandToOverflowMenu(tree);
EncodedImage placeholder = EncodedImage.createFromImage(Image.createImage(hi.getWidth(), hi.getWidth() / 5, 0xffff0000), true);
String photoURL = "https://awoiaf.westeros.org/images/thumb/9/93/AGameOfThrones.jpg/400px-AGameOfThrones.jpg";
StringBuilder fsPath = new StringBuilder(FileSystemStorage.getInstance().getAppHomePath());
fsPath.append("400px-AGameOfThrones.jpg");
URLImage background = URLImage.createToStorage(placeholder, fsPath.toString(), photoURL);
background.fetch();
Style stitle = hi.getToolbar().getTitleComponent().getUnselectedStyle();
stitle.setBgImage(background);
stitle.setBackgroundType(Style.BACKGROUND_IMAGE_SCALED_FILL);
stitle.setPaddingUnit(Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS, Style.UNIT_TYPE_DIPS);
stitle.setPaddingTop(15);
SpanButton credit = new SpanButton("Link");
credit.addActionListener((e) -> Display.getInstance().execute("https://awoiaf.westeros.org/index.php/A_Game_of_Thrones"));
hi.add(new SpanLabel("A")).
add(new Label("B", "Heading")).
add(credit);
ComponentAnimation title = hi.getToolbar().getTitleComponent().createStyleAnimation("Title", 200);
hi.getAnimationManager().onTitleScrollAnimation(title);
hi.show();
Which was taken from https://www.codenameone.com/javadoc/com/codename1/ui/URLImage.html
The tree is only to see if the image was saved in the Storage.
You are mixing Storage & FileSystemStorage which are very different things see this.
You can use storage which is a flat set of "files" and that's what URLImage.createToStorage does. But then you need to use the Storage API to work with that and it might not be visible in the FileSystemStorage API.
Alternatively you might be looking for URLImage.createToFileSystem().

Custom DrawingVisual making application sluggish

I'm wanting to render a bezier curve that will contain many hundreds of points. This curve doesn't need to be hit testable or interactable in any way, so I thought I'd try a Visual as that seems to be the most light weight.
Using the code below though, why is it causing the rest of the application to run slowly? for example, window resizing is very slow.
I'm just looking for the most efficient way to render curves without any of the input handling functionality (even with this example, you can hook up to the MouseOver event and it will only fire when your cursor is actually over the lines, so it looks like I'm still paying for that (setting IsHitTestVisiable doesn't seem to help with the performance))
public class VisualHost : FrameworkElement
{
VisualCollection _children;
public VisualHost()
{
_children = new VisualCollection(this);
_children.Add(CreateDrawingVisualRectangle());
}
DrawingVisual CreateDrawingVisualRectangle()
{
var drawingVisual = new DrawingVisual();
var drawingContext = drawingVisual.RenderOpen();
var geometry = new StreamGeometry();
using (var ctx = geometry.Open())
{
ctx.BeginFigure(new Point(0, 0), false, false);
var r = new Random();
for (int i = 0; i < 500; ++i)
{
var p1 = new Point(r.Next(0, 1000), r.Next(0, 1000));
var p2 = new Point(r.Next(0, 1000), r.Next(0, 1000));
ctx.QuadraticBezierTo(p1, p2, true, false);
}
}
geometry.Freeze();
drawingContext.DrawGeometry(null, new Pen(Brushes.Red, 1), geometry);
drawingContext.Close();
return drawingVisual;
}
protected override int VisualChildrenCount
{
get { return _children.Count; }
}
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= _children.Count)
{
throw new ArgumentOutOfRangeException();
}
return _children[index];
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
Content = new VisualHost();
}
}
You could use a BitmapCache to create a bitmap that caches the rendering of the DrawingVisual...so that when your FrameworkElement is invalided (due to the sizing) the cached bitmap is used to provide the "visual bits", instead of the slower route of having to render the drawing instructions inside of the "DrawingVisual" again (i.e. what was described by StreamGeometry in the drawingcontext).
DrawingVisual CreateDrawingVisualRectangle()
{
var drawingVisual = new DrawingVisual();
var drawingContext = drawingVisual.RenderOpen();
var geometry = new StreamGeometry();
using (var ctx = geometry.Open())
{
ctx.BeginFigure(new Point(0, 0), false, false);
var r = new Random();
for (int i = 0; i < 500; ++i)
{
var p1 = new Point(r.Next(0, 1000), r.Next(0, 1000));
var p2 = new Point(r.Next(0, 1000), r.Next(0, 1000));
ctx.QuadraticBezierTo(p1, p2, true, false);
}
}
geometry.Freeze();
drawingContext.DrawGeometry(null, new Pen(Brushes.Red, 1), geometry);
drawingContext.Close();
drawingVisual.CacheMode = new BitmapCache();
return drawingVisual;
}

how to change pie chart colors of JFreeChart?

how to customize the colors of JFreeChart graphic.
lets see my java code :
private StreamedContent chartImage ;
public void init(){
JFreeChart jfreechart = ChartFactory.createPieChart("title", createDataset(), true, true, false);
File chartFile = new File("dynamichart");
ChartUtilities.saveChartAsPNG(chartFile, jfreechart, 375, 300);
chartImage = new DefaultStreamedContent(new FileInputStream( chartFile), "image/png");
}
public PieDataset createDataset() {
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("J-2", 10);
dataset.setValue("J-1", 15);
dataset.setValue("J", 50);
dataset.setValue("J+1", 20);
dataset.setValue("J+2", 15);
return dataset;
}
html page :
<p:graphicImage id="MyImage" value="#{beanCreateImage.chartImage}" />
You can change the color of single pieces like this:
JFreeChart chart = ChartFactory.createPieChart("title", createDataset(), true, true, false);
PiePlot plot = (PiePlot) chart.getPlot();
plot.setSectionPaint("J+1", Color.black);
plot.setSectionPaint("J-1", new Color(120, 0, 120));
// or do this, if you are using an older version of JFreeChart:
//plot.setSectionPaint(1, Color.black);
//plot.setSectionPaint(3, new Color(120, 0, 120));
So with your code, all the pies are colored automatically, after my code changes, the J-1 and J+1 have a fixed color, the rest gets automatically colored.
To set the colous for a chart you can implement the DrawingSupplier inferface in this case I've used DefaultDrawingSupplier:
public class ChartDrawingSupplier extends DefaultDrawingSupplier {
public Paint[] paintSequence;
public int paintIndex;
public int fillPaintIndex;
{
paintSequence = new Paint[] {
new Color(227, 26, 28),
new Color(000,102, 204),
new Color(102,051,153),
new Color(102,51,0),
new Color(156,136,48),
new Color(153,204,102),
new Color(153,51,51),
new Color(102,51,0),
new Color(204,153,51),
new Color(0,51,0),
};
}
#Override
public Paint getNextPaint() {
Paint result
= paintSequence[paintIndex % paintSequence.length];
paintIndex++;
return result;
}
#Override
public Paint getNextFillPaint() {
Paint result
= paintSequence[fillPaintIndex % paintSequence.length];
fillPaintIndex++;
return result;
}
}
Then include this code in your `init()' method
JFreeChart jfreechart = ChartFactory.createPieChart("title", createDataset(), true, true, false);
Plot plot = jfreechart.getPlot();
plot.setDrawingSupplier(new ChartDrawingSupplier());
...
You can customize the colors according to the labels while getting the data from the dataset:
// Add custom colors
PiePlot plot = (PiePlot) chart.getPlot();
for (int i = 0; i < dataset.getItemCount(); i++) {
if(dataset.getKey(i).equals("J+1")){
plot.setSectionPaint(i, Color.black);
}
}
You can also use a switch-case statement or the one you prefer.

Load an image into a PictureBox on a different thread

I am trying to load a picture that is fetched on-demand from Google's Static Maps based against a (UK) Post Code.
Lets say I have a client and the clients has an address. One of the properties of client is PostCode. I have a form that loads clients. I feed the client ID to this form's constructor and then use LINQ 2 SQL to load all sorts of information including an address.
private void LoadBranchDetails() {
Text_Update_BI_Name.Text = Branch.BranchNumber;
Text_Update_BI_Manager.Text = String.Format("{0} {1}", Branch.PharmacyManager.FirstName, Branch.PharmacyManager.LastName);
DropDownList_Update_BI_Coordinator.SelectedValue = Branch.CoordinatorID;
DropDownList_Update_BI_ComputerSystem.SelectedValue = Branch.ComputerSystemID;
Text_Update_BI_Phone.Text = Branch.PhoneNumber;
Text_Update_BI_Fax.Text = Branch.FaxNumber;
Address BranchAddress = Branch.Contact.Addresses.FirstOrDefault();
Text_Update_AI_House.Text = BranchAddress.HouseNumber;
Text_Update_AI_Street.Text = BranchAddress.Street;
Text_Update_AI_Area.Text = BranchAddress.Area;
Text_Update_AI_Post.Text = BranchAddress.PostCode;
DropDownList_Update_AI_City.SelectedValue = BranchAddress.City.OID;
MaskedText_Update_OI_NoPharmacist.Value = Branch.NumberOfPharmacists;
MaskedText_Update_OI_NoDispensers.Value = Branch.NumberOfDispensers;
MaskedText_Update_OI_NoMonFri.Value = Branch.NumberOfItemsMondayToFriday;
MaskedText_Update_OI_NoSat.Value = Branch.NumberOfItemsSaturday;
MaskedText_Update_OI_NoSun.Value = Branch.NumberOfItemsSunday;
MaskedText_Update_OI_NoAddicts.Value = Branch.NumberOfAddicts;
MaskedText_Update_OI_NoSupervised.Value = Branch.Supervised;
MaskedText_Update_OI_NoUnsupervised.Value = Branch.Unsupervised;
Check_Update_OI_ConfRoom.Checked = Branch.ConsultationRoom;
try {
PictureGoogleMaps.Image = GoogleAddressInfo.FetchMapInfo(Text_Update_AI_Post.Text).GoogleStaticMap;
} catch (Exception) {
PictureGoogleMaps.Image = Resources.DefaultGoogleMap;
}
}
The line that loads the image into the PictureGoogleMaps causes a hang in UI as the ".GoogleStaticMap" property generates the Google static image when called.
Upon searching the internet, i found this helpful example:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Declare a list of URLs and their respective picture boxes
var items = new Dictionary<string, PictureBox>
{
{ "http://www.google.com/logos/spring09.gif", new PictureBox() { Top = 0, Width = 300, Height = 80 } },
{ "http://www.google.com/logos/stpatricks_d4gwinner_eo09.gif", new PictureBox() { Top = 100, Width = 300, Height = 80 } },
{ "http://www.google.com/logos/schiaparelli09.gif", new PictureBox() { Top = 200, Width = 300, Height = 80 } },
{ "http://www.google.com/logos/drseuss09.gif", new PictureBox() { Top = 300, Width = 300, Height = 80 } },
{ "http://www.google.com/logos/valentines09.gif", new PictureBox() { Top = 400, Width = 300, Height = 80 } },
{ "http://www.google.com/logos/unix1234567890.gif", new PictureBox() { Top = 500, Width = 300, Height = 80 } },
{ "http://www.google.com/logos/charlesdarwin_09.gif", new PictureBox() { Top = 600, Width = 300, Height = 80 } },
};
foreach (var item in items)
{
var worker = new BackgroundWorker();
worker.DoWork += (o, e) =>
{
// This function will be run on a background thread
// spawned from the thread pool.
using (var client = new WebClient())
{
var pair = (KeyValuePair<string, PictureBox>)e.Argument;
e.Result = new KeyValuePair<PictureBox, byte[]>(pair.Value, client.DownloadData(pair.Key));
}
};
worker.RunWorkerCompleted += (o, e) =>
{
// This function will be run on the main GUI thread
var pair = (KeyValuePair<PictureBox, byte[]>)e.Result;
using (var stream = new MemoryStream(pair.Value))
{
pair.Key.Image = new Bitmap(stream);
}
Controls.Add(pair.Key);
};
worker.RunWorkerAsync(item);
}
}
}
Now I just need to figure out how to remove the for loop and use this in my scenario. Any ideas?
The sample code comes from this link.
Thanks.
public partial class Form1 : Form
{
private BackgroundWorker imageLoader;
public Form1()
{
InitializeComponent();
this.imageLoader = new BackgroundWorker();
this.imageLoader.DoWork += HandleOnImageLoaderDoWork;
this.imageLoader.RunWorkerCompleted += HandleImageLoaderOnRunWorkerCompleted;
this.LoadUserDetails(1);
}
private void LoadUserDetails(Int32 userID)
{
this.imageLoader.RunWorkerAsync(userID.ToString());
// get the user details
// populate the UI controls with the data....
}
private void HandleImageLoaderOnRunWorkerCompleted(Object sender, RunWorkerCompletedEventArgs e)
{
this.pictureBox1.Image = (Image)e.Result;
}
private void HandleOnImageLoaderDoWork(Object sender, DoWorkEventArgs e)
{
// simulate a web request for an image;
Thread.Sleep(3000);
Image image = Image.FromFile(#"test.jpg");
e.Result = image;
}
}
Also make sure that you show some UI notification that a background operation is in process...something like a initial image (loading.gif) in the PictureBox.
Is it that hard to remove the foreach loop? You only need to load a single picture so remove the foreach loop and pass the url of the picture and the target picturebox to the backgroundworker.

Resources