package info.opencards.ui.lastmin; import info.opencards.Utils; import info.opencards.core.Item; import info.opencards.learnstrats.leitner.LeitnerItem; import info.opencards.learnstrats.leitner.LeitnerListener; import info.opencards.learnstrats.leitner.LeitnerSystem; import info.opencards.learnstrats.leitner.LeitnerUtils; 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.TickUnits; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.labels.StandardCategoryToolTipGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.StackedBarRenderer; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.ui.GradientPaintTransformType; import org.jfree.ui.StandardGradientPaintTransformer; import javax.swing.*; import java.awt.*; import java.util.ResourceBundle; /** * A panel which shows the current learning state of the the flashcards in the current presentation. * * @author Holger Brandl */ class LeitnerStatePanel extends JPanel implements LeitnerListener { private LeitnerSystem myLeitnerSystem; private DefaultCategoryDataset dataset; private ValueAxis valueAxis; private LeitnerItem hightlightItem; private CategoryPlot plot; public LeitnerStatePanel() { setLayout(new BorderLayout()); } public void setLeitnerSystem(LeitnerSystem leitnerSystem) { assert leitnerSystem != null; if (this.myLeitnerSystem != null) this.myLeitnerSystem.removeLearnSessionChangeListener(this); this.myLeitnerSystem = leitnerSystem; this.myLeitnerSystem.addLearnSessionChangeListener(this); // setup the stacked bar chart dataset = new DefaultCategoryDataset(); final JFreeChart chart = ChartFactory.createStackedBarChart( null, // chart title null, // domain axis label // "# cards", // range axis label null, // range axis label dataset, // data PlotOrientation.VERTICAL, // the plot orientation false, // legend true, // tooltips false // urls ); plot = (CategoryPlot) chart.getPlot(); valueAxis = plot.getRangeAxis(); TickUnits units = (TickUnits) NumberAxis.createIntegerTickUnits(); valueAxis.setStandardTickUnits(units); ChartPanel chartPanel = new ChartPanel(chart); chartPanel.setPopupMenu(null); chartPanel.setDomainZoomable(false); chartPanel.setRangeZoomable(false); removeAll(); add(chartPanel, BorderLayout.CENTER); rebuildBoxBarchart(); } private void reconfigureColorEncoding() { StackedBarRenderer renderer = new StackedBarRenderer(); renderer.setGradientPaintTransformer(new StandardGradientPaintTransformer(GradientPaintTransformType.HORIZONTAL)); renderer.setItemMargin(0.0); int barIndex = 0; //blue Paint p1 = new GradientPaint(0.0f, 0.0f, new Color(0x22, 0x22, 0xFF), 0.0f, 0.0f, new Color(0x88, 0x88, 0xFF)); renderer.setSeriesPaint(barIndex, p1); renderer.setSeriesToolTipGenerator(barIndex, new StandardCategoryToolTipGenerator()); //green barIndex++; Paint p3 = new GradientPaint(0.0f, 0.0f, new Color(0x22, 0xFF, 0x22), 0.0f, 0.0f, new Color(0x88, 0xFF, 0x88)); renderer.setSeriesPaint(barIndex, p3); renderer.setSeriesToolTipGenerator(barIndex, new StandardCategoryToolTipGenerator()); if (hightlightItem != null) { //red barIndex++; Paint p2 = new GradientPaint(0.0f, 0.0f, new Color(0xFF, 0x22, 0x22), 0.0f, 0.0f, new Color(0xFF, 0x88, 0x88)); renderer.setSeriesPaint(barIndex, p2); renderer.setSeriesToolTipGenerator(barIndex, new StandardCategoryToolTipGenerator()); } plot.setRenderer(renderer); } private void rebuildBoxBarchart() { dataset.clear(); reconfigureColorEncoding(); ResourceBundle rb = Utils.getRB(); // System.out.println("cur boxes state:\n" + LeitnerUtils.print(myLeitnerSystem)); for (int i = 0; i < myLeitnerSystem.numBoxes(); i++) { java.util.List<LeitnerItem> flashCards = myLeitnerSystem.getBoxes().get(i); int numLearnt = LeitnerUtils.count(flashCards, LeitnerSystem.LEARNT); int numFailed = LeitnerUtils.count(flashCards, LeitnerSystem.FAILED); int numUnknown = LeitnerUtils.count(flashCards, LeitnerSystem.NEW); int boxIndex = i + 1; String boxName = myLeitnerSystem.numBoxes() > 5 ? boxIndex + "" : rb.getString("LeitnerStatePanel.box") + " " + boxIndex; if (hightlightItem != null & myLeitnerSystem.getBoxIndex(hightlightItem) == i) { if (hightlightItem.getState() == LeitnerSystem.NEW) numUnknown--; else numLearnt--; } dataset.addValue(numUnknown, "New flashcards", boxName); // dataset.addValue(numFailed, "Failed", boxName); dataset.addValue(numLearnt + numFailed, "Learnt", boxName); if (hightlightItem != null) { if (myLeitnerSystem.getBoxIndex(hightlightItem) == i) { dataset.addValue(1, "Current flashcard", boxName); } else { dataset.addValue(0, "Current flashcard", boxName); } } } valueAxis.setLowerBound(0); valueAxis.setUpperBound(Math.max(myLeitnerSystem.getAllCards().size(), 1) * 1.1); valueAxis.setAutoRange(false); revalidate(); } public void newCard(Item flashcard) { rebuildBoxBarchart(); } public void boxingChanged(Item... movedCards) { rebuildBoxBarchart(); } public void removedCard(Item flashcard) { rebuildBoxBarchart(); } /** * Highlights an item of a leitner system. */ public void higlightItem(Item item) { assert item instanceof LeitnerItem; this.hightlightItem = (LeitnerItem) item; rebuildBoxBarchart(); } }