package br.ufpr.c3sl.view.retroaction;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import javax.swing.AbstractButton;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.basic.BasicRadioButtonUI;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableRowSorter;
import javax.swing.text.View;
import br.ufpr.c3sl.model.Mistake;
public class PaginateMistakes extends JPanel {
private static final long serialVersionUID = 1L;
private RadioButtonUI ui = new RadioButtonUI();
private int pageSize = 5;
private MistakesTableModel model = new MistakesTableModel();
private TableRowSorter<MistakesTableModel> sorter = new TableRowSorter<MistakesTableModel>(model);
private Box box = Box.createHorizontalBox();
public PaginateMistakes() {
super(new BorderLayout());
JTable table = new JTable(model) {
private static final long serialVersionUID = -2359027001994434574L;
public Component prepareRenderer(TableCellRenderer tcr,
int row, int column) {
Component c = super.prepareRenderer(tcr, row, column);
if (isRowSelected(row)) {
c.setForeground(getSelectionForeground());
c.setBackground(getSelectionBackground());
} else {
c.setForeground(getForeground());
c.setBackground((row % 2 == 0) ? new Color(240, 255, 250)
: Color.WHITE);
}
return c;
}
};
//invisible column
table.getColumnModel().getColumn(0).setMaxWidth(10);
table.getColumnModel().getColumn(0).setPreferredWidth(10);
//table.setIntercellSpacing(new Dimension());
table.setShowGrid(false);
table.setRowSorter(sorter);
table.getTableHeader().setBackground(Color.white);
add(new JScrollPane(table));
add(box, BorderLayout.SOUTH);
setPreferredSize(new Dimension(550, 208));
showPages(10, 1);
}
public boolean contaisMistakes(){
return model.contaisMistakes();
}
public void addMistake(Mistake mistake){
model.addMistake(mistake);
}
public void addMistakes(List<Mistake> mistakesList){
model.addMistakes(mistakesList);
}
public void showFirstPage(){
showPages(10, 1);
}
@SuppressWarnings("unchecked")
private void showPages(final int itemsPerPage, final int currentPageIndex) {
sorter.setRowFilter(filter(itemsPerPage, currentPageIndex - 1));
ArrayList<JRadioButton> l = new ArrayList<JRadioButton>();
int startPageIndex = currentPageIndex - pageSize;
if (startPageIndex <= 0)
startPageIndex = 1;
int maxPageIndex = (model.getRowCount() / itemsPerPage) + 1;
int endPageIndex = currentPageIndex + pageSize - 1;
if (endPageIndex > maxPageIndex)
endPageIndex = maxPageIndex;
if (currentPageIndex > 1)
l.add(createRadioButtons(itemsPerPage, currentPageIndex - 1,
"Prev"));
for (int i = startPageIndex; i <= endPageIndex; i++)
l.add(createLinks(itemsPerPage, currentPageIndex, i - 1));
if (currentPageIndex < maxPageIndex)
l.add(createRadioButtons(itemsPerPage, currentPageIndex + 1,
"Next"));
box.removeAll();
ButtonGroup bg = new ButtonGroup();
box.add(Box.createHorizontalGlue());
for (JRadioButton r : l) {
box.add(r);
bg.add(r);
}
box.add(Box.createHorizontalGlue());
box.revalidate();
box.repaint();
l.clear();
}
private JRadioButton createLinks(final int itemsPerPage, final int current,
final int target) {
JRadioButton radio = new JRadioButton("" + (target + 1)) {
private static final long serialVersionUID = 7825727201629193035L;
protected void fireStateChanged() {
ButtonModel model = getModel();
if (!model.isEnabled()) {
setForeground(Color.GRAY);
} else if (model.isPressed() && model.isArmed()) {
setForeground(Color.GREEN);
} else if (model.isSelected()) {
setForeground(Color.RED);
}
super.fireStateChanged();
}
};
radio.setForeground(Color.BLACK);
radio.setUI(ui);
if (target + 1 == current) {
radio.setSelected(true);
}
radio.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showPages(itemsPerPage, target + 1);
}
});
return radio;
}
private JRadioButton createRadioButtons(final int itemsPerPage,
final int target, String title) {
JRadioButton radio = new JRadioButton(title);
radio.setForeground(Color.black);
radio.setUI(ui);
radio.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showPages(itemsPerPage, target);
}
});
return radio;
}
@SuppressWarnings("rawtypes")
private RowFilter filter(final int itemsPerPage, final int target) {
return new RowFilter() {
public boolean include(Entry entry) {
int ei = (Integer) entry.getIdentifier();
return (target * itemsPerPage <= ei && ei < target * itemsPerPage + itemsPerPage);
}
};
}
}
/***********************************************************************/
class RadioButtonUI extends BasicRadioButtonUI {
public Icon getDefaultIcon() {
return null;
}
private static Dimension size = new Dimension();
private static Rectangle rec1 = new Rectangle();
private static Rectangle rec2 = new Rectangle();
private static Rectangle rec3 = new Rectangle();
public synchronized void paint(Graphics g, JComponent c) {
AbstractButton b = (AbstractButton) c;
ButtonModel model = b.getModel();
Font f = c.getFont();
g.setFont(f);
FontMetrics fm = c.getFontMetrics(f);
Insets i = c.getInsets();
size = b.getSize(size);
rec1.x = i.left;
rec1.y = i.top;
rec1.width = size.width - (i.right + rec1.x);
rec1.height = size.height - (i.bottom + rec1.y);
rec2.x = rec2.y = rec2.width = rec2.height = 0;
rec3.x = rec3.y = rec3.width = rec3.height = 0;
String text = SwingUtilities.layoutCompoundLabel(c, fm, b.getText(),
null, b.getVerticalAlignment(), b.getHorizontalAlignment(), b
.getVerticalTextPosition(), b
.getHorizontalTextPosition(), rec1, rec2, rec3, 0);
if (c.isOpaque()) {
g.setColor(b.getBackground());
g.fillRect(0, 0, size.width, size.height);
}
if (text == null)
return;
g.setColor(b.getForeground());
if (!model.isSelected() && !model.isPressed() && !model.isArmed()
&& b.isRolloverEnabled() && model.isRollover()) {
g.drawLine(rec1.x, rec1.y + rec1.height, rec1.x + rec1.width,
rec1.y + rec1.height);
}
View v = (View) c.getClientProperty(BasicHTML.propertyKey);
if (v != null) {
v.paint(g, rec3);
} else {
paintText(g, b, rec3, text);
}
}
}
/***********************************************************************/
class MistakesTableModel extends DefaultTableModel {
private static final long serialVersionUID = 1118824776778151336L;
private Hashtable<Integer, Mistake> map;
private int mistakeID; //this is necessary because BD4O doesn't support id
MistakesTableModel() {
addColumn("");
addColumn("Exercise");
addColumn("Resposta");
addColumn("Titulo do Erro");
addColumn("Ocorrido em:");
map = new Hashtable<Integer, Mistake>();
}
public boolean contaisMistakes(){
return !map.isEmpty();
}
public void addMistake(Mistake mistake){
map.put(mistakeID, mistake);
insertRow(0, new Object[] {mistakeID, mistake.getExercise(),
mistake.getMistakeInfo().getAnswer(),
mistake.getMistakeInfo().getTitle(),
mistake.getCreatedAtTime(),});
mistakeID++;
}
public void addMistakes(List<Mistake> list){
for (Mistake mistake : list) {
addMistake(mistake);
}
}
@Override
public boolean isCellEditable(int row, int column) {
final Mistake mistake = map.get(getValueAt(row, 0));
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
RetroactionFrame.createAndShowGUI(mistake);
}
});
return false;
}
}