Displaying all XYSeries at once in jFreeChart for improving speed - java

Suppose that we need to display multiple XYSeries in a single XYSeriesCollection. My problem is that every time I add a XYSeries, the JFreeChart wants to update the chart and that slows down the process of displaying multiple XYSeries.
What I want is similar to this:
// Do not update the chart
XYSeriesCollection.add(XYSeries1)
XYSeriesCollection.add(XYSeries2)
...
XYSeriesCollection.add(XYSeries10)
// Update the chart
How can I do this?

Construct a new XYSeriesCollection having the desired series, and invoke setDataset() on the XYPlot. This will generate a single DatasetChangeEvent.
Addendum: Here's an SSCCE that updates N series, each having N2 values. As this is a performance question, the example may be helpful in profiling.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.*;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Day;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
public class ChartPanelTest {
private static final int N = 16;
private static final Random random = new Random();
private static XYDataset createDataset() {
TimeSeriesCollection tsc = new TimeSeriesCollection();
for (int j = 0; j < N; j++) {
TimeSeries series = new TimeSeries("Data" + j);
Day current = new Day();
for (int i = 0; i < N * N; i++) {
series.add(current, random.nextGaussian());
current = (Day) current.next();
}
tsc.addSeries(series);
}
return tsc;
}
private static JFreeChart createChart(final XYDataset dataset) {
JFreeChart chart = ChartFactory.createTimeSeriesChart(
"Test", "Day", "Value", dataset, false, false, false);
return chart;
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
XYDataset dataset = createDataset();
JFreeChart chart = createChart(dataset);
final XYPlot plot = chart.getXYPlot();
ChartPanel chartPanel = new ChartPanel(chart) {
#Override
public Dimension getPreferredSize() {
return new Dimension(600, 300);
}
};
f.add(chartPanel);
JPanel p = new JPanel();
p.add(new JButton(new AbstractAction("New") {
#Override
public void actionPerformed(ActionEvent e) {
plot.setDataset(createDataset());
}
}));
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}

Looking at the documentation for XYSeriesCollection (assuming add should be addSeries) there is no method addAll (or similar).
If you want, you could extend XYSeriesCollection and implement addAll. In this method, you could temporarily disable all listeners before adding and re-add them after. However, this would probably be a bad idea, and would definitely need to be synchronized:
it would produce unpredictable polymorphism behavior
it would require reflection hacks, as AbstractDataset.listenerList is private
it could generate a security exception
it would not be thread safe
So the short answer is no, it is not feasible.
… but this is a starting point for how you could do it:
Field field = getClass().getDeclaredField("listenerList");
field.setAccessible(true);
EventListenerList ell = field.get(this);
// go from here
field.setAccessible(false);

Related

How can I read all values on crossline in JFreeChart? [duplicate]

On an XYPlot, I want the coordinates of mouse displayed as hint near to mouse, but only when (the mouse) move on chart! In another words, when the crosshair moves to another point, the positioning of the coordinate values would move too, following the crosshair.
Also 1 horizontal line and 1 vertical line will be drawn, that intersects specifically at the point that mouse is over on.
Is this possible?
Until now I can get the coordinates and printed on console using ChartMouseListener and chartMouseMoved method.
This is my project and how I want to be the chart with mouse.
JFreeChart has quite flexible support for crosshairs. To do what you described I would use an Overlay on the ChartPanel, and update the crosshairs from your ChartMouseListener. Here is a self-contained example (which I'll add to the collection of demos that we ship with the JFreeChart Developer Guide):
package org.jfree.chart.demo;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.geom.Rectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartMouseEvent;
import org.jfree.chart.ChartMouseListener;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.panel.CrosshairOverlay;
import org.jfree.chart.plot.Crosshair;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.RectangleEdge;
/**
* A demo showing crosshairs that follow the data points on an XYPlot.
*/
public class CrosshairOverlayDemo1 extends JFrame implements ChartMouseListener {
private ChartPanel chartPanel;
private Crosshair xCrosshair;
private Crosshair yCrosshair;
public CrosshairOverlayDemo1(String title) {
super(title);
setContentPane(createContent());
}
private JPanel createContent() {
JFreeChart chart = createChart(createDataset());
this.chartPanel = new ChartPanel(chart);
this.chartPanel.addChartMouseListener(this);
CrosshairOverlay crosshairOverlay = new CrosshairOverlay();
this.xCrosshair = new Crosshair(Double.NaN, Color.GRAY, new BasicStroke(0f));
this.xCrosshair.setLabelVisible(true);
this.yCrosshair = new Crosshair(Double.NaN, Color.GRAY, new BasicStroke(0f));
this.yCrosshair.setLabelVisible(true);
crosshairOverlay.addDomainCrosshair(xCrosshair);
crosshairOverlay.addRangeCrosshair(yCrosshair);
chartPanel.addOverlay(crosshairOverlay);
return chartPanel;
}
private JFreeChart createChart(XYDataset dataset) {
JFreeChart chart = ChartFactory.createXYLineChart("Crosshair Demo",
"X", "Y", dataset);
return chart;
}
private XYDataset createDataset() {
XYSeries series = new XYSeries("S1");
for (int x = 0; x < 10; x++) {
series.add(x, x + Math.random() * 4.0);
}
XYSeriesCollection dataset = new XYSeriesCollection(series);
return dataset;
}
#Override
public void chartMouseClicked(ChartMouseEvent event) {
// ignore
}
#Override
public void chartMouseMoved(ChartMouseEvent event) {
Rectangle2D dataArea = this.chartPanel.getScreenDataArea();
JFreeChart chart = event.getChart();
XYPlot plot = (XYPlot) chart.getPlot();
ValueAxis xAxis = plot.getDomainAxis();
double x = xAxis.java2DToValue(event.getTrigger().getX(), dataArea,
RectangleEdge.BOTTOM);
double y = DatasetUtilities.findYValue(plot.getDataset(), 0, x);
this.xCrosshair.setValue(x);
this.yCrosshair.setValue(y);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
CrosshairOverlayDemo1 app = new CrosshairOverlayDemo1(
"JFreeChart: CrosshairOverlayDemo1.java");
app.pack();
app.setVisible(true);
}
});
}
}

Rendering Swing component smoothly every 500 millisecond

I am facing rendering problem when I call paintComponent() every 500 millisecond to show updated charts. I have around 30 barcharts created by using JFreeChart on Panel.
Rendering with error and
How can I solve this problem?
private void ShowGraphs() {
FirstChart.removeAll();
SecondChart.removeAll();
ThirdChart.removeAll();
FirstChart.add(Label1);
SecondChart.add(Label2);
ThirdChart.add(Label3);
ChartUpdate(P1,FirstChart);
ChartUpdate(P2,SecondChart);
ChartUpdate(P3,ThirdChart);
//FirstChart, SecondChart, ThirdChart is JPanels
//Tabb is JTabbedPane
paintComponents(Tabb.getGraphics());
}
This code is called every 500 milliseconds and ChartUpdate(MyObject, Panel) is chart building function on Panel using MyObject's info.
Don't replace the view component. Instead, update the corresponding model and the listening view will update itself in response. In the example below, each ChartPanel returned by createPane() has a Swing Timer that updates its XYSeries every 500 ms.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
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/38512314/230513
* #see http://stackoverflow.com/a/15715096/230513
* #see http://stackoverflow.com/a/11949899/230513
*/
public class Test {
private static final int N = 128;
private static final Random random = new Random();
private int n = 1;
private void display() {
JFrame f = new JFrame("TabChart");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel p = new JPanel(new GridLayout(0, 1));
for (int i = 0; i < 3; i++) {
p.add(createPane());
}
f.add(p, BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private ChartPanel createPane() {
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);
new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
series.add(series.getItemCount(), random.nextGaussian());
}
}).start();
JFreeChart chart = ChartFactory.createXYLineChart("Test", "Domain",
"Range", dataset, PlotOrientation.VERTICAL, false, false, false);
return new ChartPanel(chart) {
#Override
public Dimension getPreferredSize() {
return new Dimension(480, 240);
}
};
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Test().display();
}
});
}
}

Time series chart, X axis tick labels turning into

I am using JFreeChart to make a barchart vs time. For some reason on these charts, the tick labels on the x axis turn into "..." occasionally. There seems like there is plenty of room for the labels to expand, but instead it just cuts off the whole thing. How can I fix this.
I tried uploading a picture using the image button, but it does not seem to be working.
Here is code with a similar set up to my project. Strangely it acted different then what is happening to my build. On mine instead of saying "Hou...", it just says "...". Ignore comments and all other uneeded things please.
package dataDisplay;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
public class mockTest extends JPanel{
ChartPanel chartPanel;
JFreeChart chart;
CategoryAxis domainAxis;
NumberAxis rangeAxis;
public mockTest()
{
//Mock data
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
int[] times = new int[]{1,2,3,4,5,6,7,8,9,10,11,12};
for ( int i = 0; i < times.length; i++ ){
dataset.addValue(times[i], "Time", "Houreee" + String.valueOf(i+1));;
}
CategoryPlot plot = new CategoryPlot();
//create the plot
//add the first dataset, and render as bar values
CategoryItemRenderer renderer = new BarRenderer();
plot.setDataset(0,dataset);
plot.setRenderer(0,renderer);
//set axis
domainAxis = new CategoryAxis("Time");
rangeAxis = new NumberAxis("Value");
plot.setDomainAxis(0,domainAxis);
plot.setRangeAxis(rangeAxis);
chart = new JFreeChart(plot);
chartPanel = new ChartPanel( chart );
this.addComponentListener(new ComponentAdapter() {
#Override
/**
* Makes it so it does not stretch out text. Resizes the fonts to scale with the screen width..
*/
public void componentResized(ComponentEvent e) {
chartPanel.setMaximumDrawHeight(e.getComponent().getHeight());
chartPanel.setMaximumDrawWidth(e.getComponent().getWidth());
chartPanel.setMinimumDrawWidth(e.getComponent().getWidth());
chartPanel.setMinimumDrawHeight(e.getComponent().getHeight());
// Makes the font size scale according to the width of the chart panel.
rangeAxis.setLabelFont(new Font("SansSerif", Font.PLAIN,e.getComponent().getWidth()/60));
domainAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN,e.getComponent().getWidth()/80));
rangeAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN,e.getComponent().getWidth()/75));
}
});
this.add(chartPanel, "Center");
}
public static void main (String[] args)
{
// Get the default toolkit
Toolkit toolkit = Toolkit.getDefaultToolkit();
// Get the current screen size
Dimension scrnsize = toolkit.getScreenSize();
int scrnWidth= (int)scrnsize.getWidth();
int scrnHeight = (int) scrnsize.getHeight();
JFrame J= new JFrame();
JPanel jP = new JPanel();
J.setContentPane(jP);
J.setSize(scrnWidth, scrnHeight);
jP.setBackground(Color.white);
jP.setBounds(0,0,scrnWidth,scrnHeight);
int xPercent= 50;
int yPercent = 50;
int widthPercent=50;
int heightPercent=43;
jP.setLayout(null);
jP.setSize(scrnWidth, scrnHeight);
mockTest b= new mockTest();
jP.add(b);
b.setBounds(new Rectangle((int)(scrnWidth*((double)xPercent/100)),(int)(scrnHeight*((double)yPercent/100)),(int)(scrnWidth*((double)widthPercent/100)),(int)(scrnHeight*((double)heightPercent/100))));
J.setUndecorated(true);
J.setVisible(true);
}
Don't use a null layout; let the layout manager do the work. The default layout of JPanel is FlowLayout, which ignores your subsequent changes. In the example below,
The chartPanel is given a GridLayout; when added to the enclosing frame's CENTER, the chart will be free to grow as the frame is resized.
Avoid unnecessarily nested panels.
Use setExtendedState() to maximize the frame.
If necessary, use one of the approaches suggested here to alter the chart's initial size.
If you choose to alter a Font, use deriveFont() to avoid abrupt disparities in the user's chosen settings.
import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
/** #see https://stackoverflow.com/a/31014252/230513 */
public class Test {
public void display() {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
for (int i = 0; i < 12; i++) {
dataset.addValue(i, "Time", "Hours" + String.valueOf(i + 1));
}
CategoryPlot plot = new CategoryPlot();
CategoryItemRenderer renderer = new BarRenderer();
plot.setDataset(0, dataset);
plot.setRenderer(0, renderer);
CategoryAxis domainAxis = new CategoryAxis("Time");
NumberAxis rangeAxis = new NumberAxis("Value");
plot.setDomainAxis(0, domainAxis);
plot.setRangeAxis(rangeAxis);
JFreeChart chart = new JFreeChart(plot);
ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setLayout(new GridLayout());
JFrame f = new JFrame();
f.add(chartPanel);
f.setExtendedState(f.getExtendedState() | JFrame.MAXIMIZED_BOTH);
f.setUndecorated(true);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Test()::display);
}
}

JFreeChart x axis scale

I have a JFree XY Line chart which always starts at x = 0. Then based on user defined settings from a properties file, the application increments based on that number (this represents the time in minutes).
For example, x = 0 to start the user defined setting is 5 so the scale goes 0, 5, 10, 15, 20…, or the user setting is 3 so it goes 0, 3, 6, 9, 12… Pretty simple.
The issue I am having is the way in which the graph starts. If I start at 0, then 0 is in the middle of the graph rather than at the bottom left with -0.0000005, -0.000004, -0.000003… 0.000000 , 0.000001 , 0.000002… 0.000005
How can I just manually add the scale at the bottom, i.e. define it should be increments of 2 and then maintain it?
You should use NumberAxis, which contains a lot of methods to define the scale of your chart.
Example :
// Create an XY Line chart
XYSeries series = new XYSeries("Random Data");
series.add(1.0, 500.2);
series.add(10.0, 694.1);
XYSeriesCollection data = new XYSeriesCollection(series);
JFreeChart chart = ChartFactory.createXYLineChart("XY Series Demo", "X", "Y", data,
PlotOrientation.VERTICAL,
true, true, false);
// Create an NumberAxis
NumberAxis xAxis = new NumberAxis();
xAxis.setTickUnit(new NumberTickUnit(2));
// Assign it to the chart
XYPlot plot = (XYPlot) chart.getPlot();
plot.setDomainAxis(xAxis);
Based on this example, here's an sscce that uses setTickUnit() to adjust the domain axis tick unit dynamically, starting from the value 5.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.NumberTickUnit;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
/** #see https://stackoverflow.com/a/14167983/230513 */
public class SSCCE {
private static final int COUNT = 100;
private static final int UNITS = 5;
private static final Random r = new Random();
public static void main(String[] args) {
XYSeries series = new XYSeries("Data");
for (int i = 0; i < COUNT; i++) {
series.add(i, r.nextGaussian());
}
XYSeriesCollection data = new XYSeriesCollection(series);
final JFreeChart chart = ChartFactory.createXYLineChart("TickUnits",
"X", "Y", data, PlotOrientation.VERTICAL, true, true, false);
XYPlot plot = (XYPlot) chart.getPlot();
final NumberAxis xAxis = (NumberAxis) plot.getDomainAxis();
xAxis.setTickUnit(new NumberTickUnit(UNITS));
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame("TickUnitDemo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new ChartPanel(chart));
final JSpinner spinner = new JSpinner(
new SpinnerNumberModel(UNITS, 1, COUNT, 1));
spinner.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
JSpinner s = (JSpinner) e.getSource();
Number n = (Number) s.getValue();
xAxis.setTickUnit(new NumberTickUnit(n.intValue()));
}
});
JPanel p = new JPanel();
p.add(new JLabel(chart.getTitle().getText()));
p.add(spinner);
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}

java Swing Application Freezes when call to jpcapCaptor.openDevice method

I am developing some bandwidth utilization monitor tool using jpcap.
what am i doing:-
1. i created a radio buttons panel containing the list of all the network interfaces that is present on system, and user has to choose one of them.
2. a jfreechart panel (dynamic) that will show the real time graph of bandwidth utilization when user clicks GO! button.
problem:-
i have added following in ActionListener in GO! button
try{captor = JpcapCaptor.openDevice(devices[selecteddevice], 65535,true, 20);}catch(Exception e){}
timer.start();
captor.loopPacket(-1,new PacketPrinter());
so when i run the program GUI comes with radiobutton panel and jfreechart panel but when i select an option and press GO! application freezes and chart panel does not show any dynamic updation.
when i commented out the JpcapCaptor.openDevice(devices[selecteddevice], 65535,true, 20);
then when i press GO! button, everything works,for example timer starts and chart panel is being updated.(but as captor is null so it is not capturing any data)
Please Help me!!!
my system is ubuntu 10.04, jpcap 0.7
my code is as follows:-
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.DynamicTimeSeriesCollection;
import org.jfree.data.time.Second;
import org.jfree.data.xy.XYDataset;
import java.util.List;
import java.util.ArrayList;
import jpcap.*;
import jpcap.packet.*;
import java.util.*;
import java.awt.event.*;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.*;
public class Sniffer extends JPanel
{
private static jpcap.NetworkInterface[] devices;
private static int selecteddevice=-1;
JFrame frame;
public static JpcapCaptor captor;
private static final String TITLE="Bandwidth Utilization Meter";;
public static List<Packet> packets;
public static Timer timer;
public static ArrayList<JRadioButton> radioButtonArray = new ArrayList<JRadioButton>();
private ButtonGroup group= new ButtonGroup();
public static JButton go;
JFreeChart chart;
static DynamicTimeSeriesCollection dataset;
public Sniffer()
{
packets = new ArrayList<Packet>();
dataset =new DynamicTimeSeriesCollection(1,120, new Second());
dataset.setTimeBase(new Second(0, 0, 0, 2, 1, 2011));
dataset.addSeries(new float[0], 0, "PPP0 Bandwidth Utilization Meter");
chart = createChart(dataset);
getDevices();
timer = new Timer(1000,new ActionListener(){
public void actionPerformed(ActionEvent e)
{ long tlen=0;
List<Packet> temp = new ArrayList<Packet>(packets);
packets.clear();
for(Packet i : temp)
{
tlen+=i.len;
}
float[] newData = new float[1];
newData[0]=(float)tlen/1024;
dataset.advanceTime();
dataset.appendData(newData);
}});
setGUI();
}
void setGUI()
{
setLayout(new BorderLayout());
frame = new JFrame();
JPanel panel = new JPanel(new GridLayout(devices.length, 1));
for (JRadioButton combo : radioButtonArray)
{
panel.add(combo);
}
JScrollPane scrollPane = new JScrollPane(panel);
go= new JButton("GO!");
go.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ee)
{
//problem starts here.............
try{captor = JpcapCaptor.openDevice(devices[selecteddevice], 65535,true, 20);}catch(Exception e){}
timer.start();
captor.loopPacket(-1,new PacketPrinter());
//.....................................
}
}
);
go.setEnabled(false);
panel.add(go);
add(scrollPane, BorderLayout.CENTER);
scrollPane.setSize(300,300);
JFrame.setDefaultLookAndFeelDecorated(true);
frame.setLayout(new GridLayout(2, 0));
frame.add(scrollPane);
frame.add(new ChartPanel(chart));
frame.setSize(1024, 768);
frame.setTitle("BW");
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void getDevices()
{
devices = JpcapCaptor.getDeviceList();
for(int i=0;i<devices.length;i++)
{
String device=null;
radioButtonArray.add(new JRadioButton());
group.add(radioButtonArray.get(i));
radioButtonArray.get(i).addActionListener(new RadioButtonListener());
device= devices[i].name+" "+"("+devices[i].description+")";
radioButtonArray.get(i).setText(device);
}
}
public static void startSniffing() throws Exception
{
captor = JpcapCaptor.openDevice(devices[selecteddevice], 65535,true, 20);
}
public static void setSelectedDevice(int device)
{
selecteddevice = device;
}
public NetworkInterface getSelectedDevice()
{
if (selecteddevice == -1)
{
return null;
}
else
{
return devices[selecteddevice];
}
}
public static void main(String args[])
{
Sniffer sniffer = new Sniffer();
//sniffer.start();
}
private JFreeChart createChart(final XYDataset dataset) {
final JFreeChart xyz = ChartFactory.createTimeSeriesChart(
TITLE, "Time(Seconds)", "Bandwidth KB/s", dataset, true, true, false);
final XYPlot plot = xyz.getXYPlot();
ValueAxis domain = plot.getDomainAxis();
domain.setAutoRange(true);
ValueAxis range = plot.getRangeAxis();
range.setRange(0,1000);
return xyz;
}
}
class RadioButtonListener extends JPanel implements ActionListener {
public void actionPerformed(ActionEvent e) {
Sniffer.go.setEnabled(true);
for (JRadioButton radio : Sniffer.radioButtonArray) {
if (radio.isSelected()) {
Sniffer.setSelectedDevice(Sniffer.radioButtonArray.indexOf(radio));
}
}
}
}
class PacketPrinter implements PacketReceiver {
static long tlen;
public void receivePacket(Packet packet) {
Sniffer.packets.add(packet);
}
}
Don't block the EDT. Put the time consuming task in a SwingWorker.

Categories

Resources