package org.mansart.mongocount.gui; import org.jfree.chart.ChartPanel; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.time.*; import org.jfree.ui.ExtensionFileFilter; import org.mansart.mongocount.Configuration; import org.mansart.mongocount.Counter; import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.io.File; import java.io.IOException; public final class Window extends JPanel { private Configuration configuration = null; private Counter counter = null; private TimeSeries data = null; private JFreeChart chart = null; private ChartPanel chartPanel = null; private JButton configurationButton = new JButton("Configure"); private JButton lifeButton = new JButton("Start"); private JButton clearButton = new JButton("Clear"); private JButton saveButton = new JButton("Save"); private JButton quitButton = new JButton("Quit"); private JDialog configurationDialog = null; public Window(Configuration configuration, Counter counter) { super(); this.configuration = configuration; this.counter = counter; this.configurationDialog = new ConfigurationDialog(configuration, this); this.setupListeners(); this.setupChart(); this.setupGraphics(); } private void setupListeners() { this.configuration.addListener(new Configuration.Listener() { @Override public void onUpdate() { String dbname = Window.this.configuration.getDbname(); String collname = Window.this.configuration.getCollname(); final String title = dbname + "." + collname; SwingUtilities.invokeLater(() -> { Window.this.data.clear(); Window.this.chart.setTitle(title); Color color = Window.this.configuration.getColor(); Window.this.chart.getXYPlot().getRenderer().setSeriesPaint(0, color); }); } @Override public void onError() { SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(Window.this, "Invalid configuration provided", "Configuration invalid", JOptionPane.ERROR_MESSAGE)); } }); this.counter.addListener(new Counter.Listener() { @Override public void onStart() { SwingUtilities.invokeLater(() -> Window.this.lifeButton.setText("Stop")); } @Override public void onStop() { SwingUtilities.invokeLater(() -> Window.this.lifeButton.setText("Start")); } @Override public void onCount(final long count) { String dbname = Window.this.configuration.getDbname(); String collname = Window.this.configuration.getCollname(); final String title = dbname + "." + collname + " : " + count; SwingUtilities.invokeLater(() -> { Window.this.chart.setTitle(title); Window.this.data.add(new Millisecond(), count); }); } @Override public void onError() { SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(Window.this, "An error occured while counting : " + Window.this.configuration, "Processing error", JOptionPane.ERROR_MESSAGE)); } }); this.configurationButton.addActionListener(e -> { Window.this.configurationDialog.setLocationRelativeTo(Window.this); Window.this.configurationDialog.setVisible(true); }); this.lifeButton.addActionListener(e -> new Thread(() -> { if (Window.this.counter.isStarted()) { Window.this.counter.stop(); } else { Window.this.counter.start(); } }).start()); this.clearButton.addActionListener(e -> Window.this.data.clear()); this.saveButton.addActionListener(e -> { JFileChooser fileChooser = new JFileChooser(); fileChooser.addChoosableFileFilter(new ExtensionFileFilter("JPEG", ".jpg")); int option = fileChooser.showSaveDialog(Window.this); if (option == JFileChooser.APPROVE_OPTION) { File file = fileChooser.getSelectedFile(); int width = Window.this.chartPanel.getWidth(); int height = Window.this.chartPanel.getHeight(); try { ChartUtilities.saveChartAsJPEG(file, Window.this.chart, width, height); } catch (IOException exception) { exception.printStackTrace(); } } }); this.quitButton.addActionListener(e -> System.exit(0)); } private void setupChart() { this.data = new TimeSeries("Counts"); TimeSeriesCollection dataset = new TimeSeriesCollection(); dataset.addSeries(this.data); DateAxis domain = new DateAxis("Time"); domain.setAutoRange(true); NumberAxis range = new NumberAxis("Count"); XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(); renderer.setBaseShapesVisible(false); renderer.setBaseSeriesVisibleInLegend(false); XYPlot plot = new XYPlot(dataset, domain, range, renderer); this.chart = new JFreeChart("Mongo Counts", plot); ChartUtilities.applyCurrentTheme(this.chart); } private void setupGraphics() { JPanel controlsPanel = new JPanel(); controlsPanel.setBorder(BorderFactory.createCompoundBorder( new EmptyBorder(5, 5, 5, 5), new TitledBorder("Controls"))); controlsPanel.setLayout(new BoxLayout(controlsPanel, BoxLayout.LINE_AXIS)); controlsPanel.add(this.configurationButton); controlsPanel.add(Box.createHorizontalGlue()); controlsPanel.add(this.lifeButton); controlsPanel.add(this.clearButton); controlsPanel.add(this.saveButton); controlsPanel.add(Box.createHorizontalGlue()); controlsPanel.add(this.quitButton); // fourth first booleans are for context menu : properties, save, print, zoom // last boolean is for enabling tooltips this.chartPanel = new ChartPanel(this.chart, false, false, false, true, false); this.chartPanel.setBorder(new EmptyBorder(0, 0, 10, 0)); this.setLayout(new BorderLayout()); this.add(this.chartPanel, BorderLayout.CENTER); this.add(controlsPanel, BorderLayout.SOUTH); } }